As I understand it the "MVC" came before the web and is often used in Desktop software for example.
If I understand correctly, the Controller runs at the time that the user will click a button and this will trigger an action.
But if we talk about web pages, the scenario is a little different, assuming the user clicks a link then it triggers an action.
But then, came me the doubt, is the home page part of a Controller?
What I mean is, the homepage is not usually performed by a user action within the website is just the home, but noticed that many PHP frameworks use a Controller for the home, is that correct?
Another doubt is in my "home" I have several items, for example:
banners
featured posts
recent posts
Each of these items would have a different Model, can I call more than one Model and a View into the Controller?
Would these be the correct steps? Or most of php frameworks are not strict?
You are completely right and I understand the confusion.
In a pure MVC approach, the Controller only listens to user actions and updates the Model accordingly. The Model then notifies the View (through the Observer design pattern) and the View updates itself, accessing the data it needs from the Model.
This is how it was done before the web, in desktop application, where the Model and the View are running concurrently, and where the Model can notify the View. The Controller doesn't set up the View.
In this pure MVC model, the example you mentioned about the homepage doesn't need a Controller indeed. The View would just render itself, accessing the data it needs through the Model. Controllers are very thin and only listen to user actions and update the Model. That's all they do.
In the web, this model is not possible, and thus there are alternative approaches. The Model can't notify the View as in the pure model, and thus what popular frameworks require you to do, is to set up the View in your Controller. That's why for your example of the homepage you need a Controller, as you will set up your view there with all the data it requires.
However, there is another approach I have been personally writing about, where Controllers don't set up the View which allow you to keep tiny Controllers. You can read about it here: A better OOP approach to building MVC applications
Thus I believe that the homepage shouldn't need a controller action at all. The View should just render itself and access the data it needs to render. The Controller's role is to handle user actions and update the model accordingly, as you said. If it does more than that, it probably violates SRP. The Controller shouldn't set up the View, instead, the View should get its own data from the Model.
Related
I am very new to MVC.
I just finished reading a book and am trying to implement what I have learned, but I am stuck. In the book and some other explanations I have read online, it's always one controller for one view, like navigation view being controlled by its controller, login form controlled by its own controller.
But I have a header with couple of navigation links, and a search form. Do I separate navigation from searching or assume searching is part of navigation and just control them all in one controller?
First of all, you seem to have the impression that "template" and "view" is the same thing. It's wrong. A properly done view will juggle multiple templates and choose which combination to use based on the current state of the model layer.
As for your navigation & search thing ... well ... it's confusing. Each link in navigation would point to either a different controller entirely or a different methods of controller. And search query would definitely be submitted to a separate controller/view pair.
The navigation+search is just a template, that is used in multiple views as part of the complete response.
I'm trying to implement mvc design pattern to my existing dating-web-app project. I believe I understood the concepts and created a login model and controller without any problems. Basically, I have a base controller which initiates a view object on construct. Than I use that object to send information to the view from within the controllers as method parameters. However, I couldn't decide how to send variables to the top menu view. Since this menu displays dynamic information (request count, notification count,etc) and included in every page of the application, only two options come to my mind:
Send information to the view from every controller, which seemed like reuse of code.
Put a seperate action in the base controller and make it called automatically when other controllers extend base controller.
Which one should I choose? Or, is there a better way to do this?
Dear Friends: It seems like more of a Conceptual problem than a programming problem. Am new to MVC and have problems in understanding what can call what. THE FLOW OF PROGRAM CONTROL.
The Problem: Controller A --Calls-->Model A--calls-->View A. Now once the View A is loaded it also contains a form for inserting comment with a sumbitt button.
Once the comments are inserted (and submitted) it calls Controller B--calls-->Mocel B. which insert data into comments table -- further it has NO View to call.
QUESTION 1: how to call the Controller A from Model B (since model B does not have a view). it is possible to load ViewA from ModelB but that will require to re-write the code that exists in Controller a already. FURTHER more i want the comment form to be inserted into many pages so will i have to reload all those pages (Views) manually.
Question2: it is possible to make comments form (Controller B and Model B) part of Controller A and Model A BUT then comment form will cease to be a re-usable module and will need to be inserted into every page that i like it to be used in.
Question3: Is there some conceptual error i an making. it is the way MCV works?
Summary:: There is a form managed by Controller B and Modal B (it has no view and it displayed as part of a page managed by Controller A, Model A and View A) Model Bafter doing its job it needs to call Controller A (so that it can refresh the page) HOW?
THANKS TO YOU BRAVE SOULS IN ADVANCE
I think your strategy is a little off starting with
Controller A --Calls-->Model A--calls-->View A
Your models really shouldn't be calling your view. The controller is usually in charge of this. Requests are made to the controller and the controller gets all the data from the model then formats/templates it using a view and outputs it to a user. Controllers should be at the center of every request.
QUESTION 1 how to call the Controller A from Model B?
Model B really shouldn't be calling a controller. MVC really isn't desinger for this. If you need data from model B get it from the controller. If you need functionality that exists in controller A refactor it into a utilty function that can be used anywhere in your app.
Question2: it is possible to make comments form (Controller B and
Model B) part of Controller A?
Yes once again this comes from a good app design. I'd imagine that one of your models is able to retrieve comments. Perhaps per user perhaps per time frame. From controller A you can call that model function. By loading the model $this->load->model('Post')
and retireving your posts $this->Post->most_recent_posts().
Question3: Is there some conceptual error i an making. it is the way
MCV works?
Yes the functions of your site are too tightly bound to their controllers and models. They hve to be more loose/general so functionality can be used in any controller.
I'd like to answer you last/main point but it would really really help to see some code.
I've just started reading up on CakePHP and everything is going pretty good so far, though I have a query on the best way to do the following:
I have a "User" model and a "UsersController" controller.
I currently have a "home" page which is controlled by the home_controller.php (obviously). The home page contains a registration for for a user.
The Question
When the form is posted from the home page, I need to access the User model (from the home controller).
What is the best practice for this task?
If I understand the situation correctly, I would post the form to some function in users controller. Then this function would save the data, or log in, or whatever. Finally make redirect back to home for example.
you can easily share one model across many controllers
var $uses = array('ModelName');
I do that with User Model and
Account Controller (Login, Register, ...)
Members Controller (Search, Listing, Profile, ...)
Overview Controller (Start Page, Home, ...)
for example. they all share the User Model.
I currently have a "home" page which is controlled by the home_controller.php (obviously) What other methods do you have in home_controller, other than index? And in Cake convention, the controller is plural, so: users, categories... Most likely, you are not aware of pages_controller and routing in Cake.
Anyway, yes, you can make a post to any controller (or even to another domain) from any page, just like any regular HTML page. echo $this->Form->create('User', array('controller'=>'users','action' => 'register')); You can read more here: http://book.cakephp.org/view/1384/Creating-Forms
In Zend Framework, I have a common use case where I need to propagate the same information in the top section of a view across a particular controller.
For example, if I have a "Book" controller, I want to display the summary book information at the top of the page, and have a tabbed interface below the book to display comments, detailed info, etc. Each tab is an action in the books controller. What is the recommended way to propagate the summary information across the views in the controller such that:
I am not continually fetching the summary book information in each action.
I am not repeating information in my views.
I though of using a Zend View Helper, a placeholder, or the action helper ($this->action...) from within the view.
Any suggestions?
Sounds like you'd want to fetch the book information in an init() method on the controller:
class MyController extends Zend_Controller_Action
{
protected $_book;
public function init()
{
// get the book data/model, etc
$book = $this->_getBook();
// if necessary, store the book for use in the actions
$this->_book = $book;
// store the book in the view
$this->view->book = $book;
}
}
If an action only renders the book info, then you can probably get away with empty action methods, letting the view scripts do their thing.
The only downside to this is that it gets the book data on every action. So if there are some actions that do not require the book data, then you'd be eating the overhead of fetching it.
I would load the tabs' contents dynamically (should be easy to integrate with your current solution via the action helper AjaxContent. Just load the action's response into your tab container.
If you decide to stick with a non-ajax solution, the code is forced to be repetitive since you need the same piece information on more than one page. A partial should be better suited for your needs since a view helper performs some kind of logic (or proxies for logic) while you only need it for presentation & markup.
The information fetched should not be that hard on your system, assuming you are using some smart cache method (perhaps one cache entry for each section/tab).