MVC - Passing data between Controller and View via Model

Have a programming question regarding your component, plug-in, extension or core hacks? Have an interesting tidbit, FAQ or programming tip you’d like to share? This is the place for you.

Moderators: tjay, seadap, Rogue4ngel, matthewhayashida

Post Reply
bengrice
Joomla! Apprentice
Joomla! Apprentice
Posts: 6
Joined: Wed Jan 30, 2008 12:23 pm

MVC - Passing data between Controller and View via Model

Post by bengrice » Wed Jan 30, 2008 12:52 pm

Hi there,
Im very new to Joomla but hav a fairly good understanding of PHP.

Basically i need to make a component for joomla and so after reading the MVC tutorials i did this successfully  :D woow!

However this is my current problem:

When i access a method in my controller i need to set some variable values and then pass these to my view so i can assign them to variables in my layout. Now in the tutorials it says that the controller is used to call methods in a model to update data then this model is passed to the view, the problem is if i access a variable from the model in the view it is like this model has been re initiated and any changes made by the controller are lost.

let me show you by code

In my controller:

Code: Select all

$model =& $this->getModel();
$model->setMyData();
      
parent::display();


In my model:

Code: Select all

var $test= 'default';

function __construct()
{
parent::__construct();
}

function getMyData()
{
return $this->test;
}
   
function setMyData()
{
$this->test = 'hello from model';
}


In my view:

Code: Select all

$word = $this->get('MyData');
$this->assignRef('greeting', $word);

note: ive tried accessing the model using the same code as the controller instead of the $this->get method

So as you can see when i call the setMyData method from the controller it sets the var 'test' to 'hello from model' however when i call get('MyData') or $model->getMyData(); from the view i get 'default' which is what i set the var to when the class is constructed.

I hope you get what im saying because iv confused myself  ??? lol

Am i doing something wrong? is there another way of passing data between controller and view?

Any help will be much much apreciated as ive been stuck on this for 3 days solid  :'(

Many thanks

Ben

radiant_tech
Joomla! Apprentice
Joomla! Apprentice
Posts: 41
Joined: Sat Dec 15, 2007 3:02 pm
Location: Washington DC Metro

Re: MVC - Passing data between Controller and View via Model

Post by radiant_tech » Mon Feb 04, 2008 10:19 pm

I believe part of your mistake is that your are creating another instance of a model through your controller.  This step is unnecessary (and perhaps the real source of error). 

The component will know which model to use based on the view you are using -- and will do this automatically.

If you only have one controller, one model and one view, make sure they all use the appropriate naming conventions as indicated in the MVC tutorial.
Denise

bengrice
Joomla! Apprentice
Joomla! Apprentice
Posts: 6
Joined: Wed Jan 30, 2008 12:23 pm

Re: MVC - Passing data between Controller and View via Model

Post by bengrice » Tue Feb 05, 2008 11:06 am

Hi there, thanks for your reply.

Didn't think any knew the answer lol  :D

Well as i didn't get any reply till now i was forces to spend many hours looking at the current components and trying to work out how they did it. after going quite  :P mad i work out  the following,

and it is sort of inline with what you were saying:

in the controller:

Code: Select all

// Create the view
$view = & $this->getView('test', 'html');

// Get/Create the model
$model = & $this->getModel('Test');

//update th model
$model->setHello();

// Push the model into the view !!!!!THIS IS THE KEY !!!!!
$view->setModel($model, true);

// Set the layout
$view->setLayout('test');

// Display the view
$view->display();


then when in the view:

Code: Select all

$hello = & $this->get('hello'); //this is how you access the model '$this' and you use the get method to call your method dropping the get. bit confusing lol

$this->assignRef('hello', $hello);

parent::display($tpl);


this now seems to work.

now i have another question lol  :D

can you call, use and pass multiple models between controller and view or is it just the one? eg if i had to model one for manipulating one table in the database and another for another table but need to update both in the controller and pass to view, if you get what i mean.

Thanks again for the reply

Ben

radiant_tech
Joomla! Apprentice
Joomla! Apprentice
Posts: 41
Joined: Sat Dec 15, 2007 3:02 pm
Location: Washington DC Metro

Re: MVC - Passing data between Controller and View via Model

Post by radiant_tech » Tue Feb 05, 2008 1:48 pm

Ben,

Prefacing my response by clarifying that I am talking strictly in terms of J! 1.5, as I have not looked at 1.0 at all.  So perhaps, we're talking past each other a bit.  However, if you are trying to understand how all this works with 1.5, you really must read the MVC tutorial that can be found here:  http://dev.joomla.org/component/option,com_jd-wiki/Itemid,/id,jbeginners:introduction/ (scroll down to Week 4).

It can be a bit thick -- particularly the last tutorial, which makes some big steps and could definitely use some further clarification in areas.  However, I think it would help you see that your controller does not need to call/create the model or the view.  It will also be extremely useful in showing how to build the back-end for your component.

In the case where your component involves more than one table, you would create additional views and models, and may also create a second controller.  Keep in mind that the view and the model are tied together.  If they are given the same name (as they should), the API recognizes which model to use to obtain your data by the view you have told to display.

Before I go into a long-winded explanation, let me know if it is indeed 1.5 that you are working with.  Then I can give a more clear example.  I'll also point you to the following post which I found very helpful: http://forum.joomla.org/index.php/topic,228926.0.html.

Regards,
Denise

bengrice
Joomla! Apprentice
Joomla! Apprentice
Posts: 6
Joined: Wed Jan 30, 2008 12:23 pm

Re: MVC - Passing data between Controller and View via Model

Post by bengrice » Tue Feb 05, 2008 3:09 pm

Ye i am using 1.5,

From what i already understood the model an view are tied together, i was just wondering that im sure the time will arrise when i need to access a method from another model. i suppose i could be missing the point, mayb i could include the model in the frist model.

i am basically thinking of models as my classes, here is an example sinario:

if got a class that has methods in for user admin, eg add user, get users info, update users info etc lets call this 'class 1'. i then hav a component that for eg logs a hit on a user. the model of this component has its own methods eg get the info from the hit eg ip address, time date, add the hit info to the database. but then say i want to find the users info. i dont want to replicate a method in the model that gets the users info when i already have this in 'class 1'. so what im saying is is there a way to either put this class in another method or even better make this class avaiable all the time, eg so i could access my user methods from my class in any models in any components?

hope you get what im saying.

also back on the old question what your saying is that i dont need to do the get model and push to the view as they will be automaticaly in the controller and view once i set the view? (providing the names are the same) if this is correct how do i access the models functions in both the controller and view? is it using the $this?

Thanks again for all your help

this is much appriciated

ben

radiant_tech
Joomla! Apprentice
Joomla! Apprentice
Posts: 41
Joined: Sat Dec 15, 2007 3:02 pm
Location: Washington DC Metro

Re: MVC - Passing data between Controller and View via Model

Post by radiant_tech » Tue Feb 05, 2008 6:18 pm

Bear with me and I'll hope to not confuse you any further.  lol

Joomla! 1.5 is replete with existing classes and methods as a lengthy review of the API Framework will show you.  Chances are that most of the methods for interacting with user data that you would want to access are already available to you through the JUser and JUserHelper classes.  ( see http://api.joomla.org/Joomla-Framework/Application/JController.html and http://api.joomla.org/Joomla-Framework/User/JUserHelper.html )

These methods can be called within your component by your controller, view, or model as is most appropriate.

i dont need to do the get model and push to the view as they will be automaticaly in the controller and view once i set the view? (providing the names are the same

Yes.

how do i access the models functions in both the controller and view?

The controller does not interact directly with the model. 

The controller receives "tasks" to perform from the URL (via task=).  Where this does not exist in the URL, the default task is display().  Other tasks might include edit(), add(), save(), myfunction(), etc.  Basic tasks are already available to you in the JController class and these can be extended in the controller(s) you create in your component.  Other completely new "task" functions can also be added to your controller(s).

If a model and view other than the default are needed, the controller tells Joomla which ones to use with the JRequest::setVar() function.  For instance, consider the following edit function within a controller:

Code: Select all

    function edit()
    {
       JRequest::setVar('view', 'route');
       JRequest::setVar('layout', 'form');
       JRequest::setVar('hidemainmenu', 1);

       parent::display();
    }

This specifies:
-- the view to be used during the edit function will be "route" (com_mycomponent/views/route/view.html.php),
-- the template that will be used for display is "form" (com_mycomponent/views/route/tmpl/form.php),
-- the model used to obtain the data will also be "route" (com_mycomponent/models/route.php).

The view is fed data by the model.  In turn it assigns this data to a variable(s) through $this->assignRef('varname', $var).  The template can then display the variable given to it by the view.  Again accessed as $this->varname.  If $varname is an object (as will usually be the case), each property will be accessed in the template with $this->varname->property.

Obviously a strong understanding of OOP (object oriented programming) is very important in this new framework.  There are good starter articles for OOP referenced in the Joomla! Beginner Introduction that I mentioned in an earlier post.

Hope all of that helps.
Denise

bengrice
Joomla! Apprentice
Joomla! Apprentice
Posts: 6
Joined: Wed Jan 30, 2008 12:23 pm

Re: MVC - Passing data between Controller and View via Model

Post by bengrice » Wed Feb 06, 2008 11:09 am

Sorry i know joomla has vast functions for user stuff, i was just giving you a scenario. so that question (re worded) would be, is there a way to include extra classes built by me that would be available in my component controllers and views, say if i had a class for encrypting and decrypting data and i needed to use it in many components (or access it from a method in my model)? eg create my own JUser class that is globally available?
hope that clarifies that one  ???

In reply to the next part of your reply,
The controller does not interact directly with the model.


Its always been my understanding that in the MVC architectural pattern the controller (and i agreewith you) retrieves and runs tasks, but it also and i quote from WIKI
Processes and responds to events, typically user actions, and may invoke changes on the model.


again from wiki this is how i understood the process to work:

  • The user interacts with the user interface in some way (e.g., presses a button).
  • A controller handles the input event from the user interface, often via a registered handler or callback.
  • The controller accesses the model, possibly updating it in a way appropriate to the user's action (e.g., controller updates user's Shopping cart).
  • A view uses the model (indirectly) to generate an appropriate user interface (e.g., the view produces a screen listing the shopping cart contents). The view gets its own data from the model. The model has no direct knowledge of the view.
  • The user interface waits for further user interactions, which begins the cycle anew.


I thought it was bad practice to carry out data manipulation in your view, now if i cant do this in my view the only place i can do it is in my controller? so logically i would need access to my model to say update an item in a cart?

Thanks for your time, i hope I'm not wasting it  :( i just want to get i proper understanding of joomla before i start writing loads of components that are wrong  :o

Ben
Last edited by bengrice on Wed Feb 06, 2008 11:12 am, edited 1 time in total.

radiant_tech
Joomla! Apprentice
Joomla! Apprentice
Posts: 41
Joined: Sat Dec 15, 2007 3:02 pm
Location: Washington DC Metro

Re: MVC - Passing data between Controller and View via Model

Post by radiant_tech » Wed Feb 06, 2008 4:30 pm

Great points Ben.  And I'll add that having this discussion is also helping me develop a more clear view of MVC architecture, etc. so thanks for that.  :)

My point in saying the controller did not interact directly with the model was really to clarify that you are not "calling" the model you need directly in the controller (as in your earlier examples).  In a sense you are ... by the fact that you set the view (in response to user events) ... which in turn defines which model is used.

Code: Select all

I thought it was bad practice to carry out data manipulation in your view

I'm not sure I follow you on this.  Are you questioning the use of $this->assignRef() in the view?  This is not a "manipulation" of the data (since the data is coming from the model), it is simply the way the data is passed to the template.

Considering the shopping cart example ...
1) the controller receives a user event (adding an item to the cart), invoking perhaps an additem() function;
2) in the controller the additem() function sets the view (via JRequest::setVar()) to display current contents of the cart to the user, lets call that viewcart, which in turn instructs the viewcart model to obtain data of current objects in the user's cart;
3) the viewcart view receives the data from the model, assigns the object to a variable and passes the variable to the template for output

At any rate, I think we're both on the right track.  Maybe with luck IanMac will stop by and give us some confirmation.  8)

As for the overall question of creating a class that can be accessed in any controller/model in the system -- I'd consider that a framework issue and don't have a clue yet if that is even possible.  You may be able to get a response direct from the dev team if you pose that question in one of the Development/Joomla! 1.5 forums.  (And I'll be looking for it.  LOL)
Denise

User avatar
ianmac
Joomla! Enthusiast
Joomla! Enthusiast
Posts: 237
Joined: Sat Sep 24, 2005 11:01 pm
Location: Toronto, Canada

Re: MVC - Passing data between Controller and View via Model

Post by ianmac » Wed Feb 06, 2008 7:08 pm

radiant_tech wrote:Great points Ben.  And I'll add that having this discussion is also helping me develop a more clear view of MVC architecture, etc. so thanks for that.  :)

My point in saying the controller did not interact directly with the model was really to clarify that you are not "calling" the model you need directly in the controller (as in your earlier examples).  In a sense you are ... by the fact that you set the view (in response to user events) ... which in turn defines which model is used.

This isn't entirely true...  the controller could manipulate a variety of models in a single task.  Joomla! by default will grab the model and view that corresponds to the controller, but these don't have to be the ones used.  Your controller may need to manipulate a variety of models to accomplish the task that it was invoked to do.

Also, some views will need to get data from more than one model.

So, we have the JView::setModel class, which takes two parameters.  The first parameter is the model object to set as the model.  The second parameter is a boolean that indicates whether or not the model should be the default model or not.

The corresponding method to be used in the view is the JView::getModel method.  This method has one parameter, which is the model name.  If the parameter is omitted, the default model will be returned.

As for other classes, this can certainly be done.  Not everything has to be a model, either.  Joomla! also frequently uses the idea of a helper.  Helper classes are classes that contain functions that are more often static - that is, they don't keep data themselves, but are utility functions.  You will notice various files in the core components called helper.php or other files in folders called helper.

You can also use just normal classes that you need as library type classes.  These may or not be models in the sense that they fit into the MVC structure of your application.

I hope this helps,
Ian
Help test my Component XML Generator Tool!
http://extensions.joomla.org/component/option,com_mtree/task,viewlink/link_id,1997/Itemid,35/
All feedback appreciated!

bengrice
Joomla! Apprentice
Joomla! Apprentice
Posts: 6
Joined: Wed Jan 30, 2008 12:23 pm

Re: MVC - Passing data between Controller and View via Model

Post by bengrice » Wed Feb 06, 2008 7:17 pm

thanks for your help ian,

so if i use JView::setModel i can set more that one model? and then use JView::getModel to get them both?

also:

You can also use just normal classes that you need as library type classes


how do i do this, because it sounds exactly what i need? sa i build a class that i want available all the time, or want to call from many controlers & views? where would i put this class and how would i access it?

thanks again

ben

User avatar
ianmac
Joomla! Enthusiast
Joomla! Enthusiast
Posts: 237
Joined: Sat Sep 24, 2005 11:01 pm
Location: Toronto, Canada

Re: MVC - Passing data between Controller and View via Model

Post by ianmac » Wed Feb 06, 2008 7:41 pm

bengrice wrote:thanks for your help ian,

so if i use JView::setModel i can set more that one model? and then use JView::getModel to get them both?

Yes.

also:

You can also use just normal classes that you need as library type classes


how do i do this, because it sounds exactly what i need? sa i build a class that i want available all the time, or want to call from many controlers & views? where would i put this class and how would i access it?

thanks again

ben


make a directory in your component, maybe called libs or something, or classes, whatever you want.  Then define the class in that file.

Then, make sure you require_once it and then instantiate your class or whatever you want.

Ian
Help test my Component XML Generator Tool!
http://extensions.joomla.org/component/option,com_mtree/task,viewlink/link_id,1997/Itemid,35/
All feedback appreciated!

bengrice
Joomla! Apprentice
Joomla! Apprentice
Posts: 6
Joined: Wed Jan 30, 2008 12:23 pm

Re: MVC - Passing data between Controller and View via Model

Post by bengrice » Wed Feb 06, 2008 11:19 pm

cool ill give this a go, thanks both for your time. much appreciated ! !

happy joomling  :D

ben


Post Reply