问题
I'm trying to learn ember.js and having a difficult time trying to make the connection between it all. I've gone through the tutorials provided on ember.js, but still a bit confused.
The model contains the data that will be saved on the server. The controller has access to the model's data and can decorate it (add its on display data) and send that to the template itself.
In the examples, they use the route class to actually get the data from the model. They associate the route with a model and just call .find() and that find() return you the list of data from the model.
I'm only using one route in my example:
My question is:
- How do you grab data from the model from the controller
- Can a controller get data from more then one model? If so, how is this done?
- If the controller has more then one function associated with it, how do you trigger the right one within the template.
Any examples would help... I've been searching around and in most cases they deal with the simple case where there is one controller linked with one model and the controller is linked with one template. What happens if the template wants to use more then one controller?
In Reference to Mike's example of Template to multiple controllers:
//index.html
<script type="text/x-handlebars" id="index">
<div {{action getMessage}} > </div>
<div {{action getTest}} > </div>
{{#each App.menuController}}
{{title}}
{{/each}}
</script>
// app.js
App.ChatController = Ember.Controller.extend({
getMessage: function() { alert("getMessage Called"); }
});
App.MenuOption = Ember.Object.extend({
title: null,
idName: null
});
App.MenuController = Ember.ArrayController.create({
content:[],
init : function()
{
// create an instance of the Song model
for(var i=0; i<menuOptions.length; i++) {
console.debug(menuOptions[i]);
this.pushObject(menuOptions[i]);
}
},
getTest: function() { alert("getTest Called"); }
});
//router.js
App.Router.map(function () {
this.resource('index', { path: '/' });
});
App.IndexRoute = Ember.Route.extend({
model: function () {
return ['a','b', 'c' ];
},
setupController: function(controller, model) {
controller.set('content', model);
},
});
App.IndexController = Ember.Controller.extend({
needs: "index"
});
From the above, as you can see I have one route "index." Within the default index template, I'm trying to figure out how to call multiple controller's action. In this case, I want to call "getMessage" which belong to App.ChatController & "getTest" which belong to App.MenuController. Currently, the "getTest" is not defined for the template's controller "index" and has not be defined by the IndexRoute as well. So do you use "needs" to link the MenuController to the IndexController so i can call the controller's getTest Method.
Updated ----------------------------------
I ended up going the render route
App.IndexRoute = Ember.Route.extend({
model: function () {
return ['a','b', 'c' ];
},
renderTemplate: function () {
this.render();
this.render('menu', { outlet: 'menu', into: 'application', controller: App.menuController });
this.render('userList', { outlet: 'userList', into: 'application', controller: App.UserListController });
}
});
This allowed me to specify a specific controller for each specific rendering.
Any advice appreciated, Thanks, D
回答1:
How do you grab data from the model from the controller
By default, a route's model (the object retured by the route's model
hook) will be injected into the controller and can be accessed via the controller's content
property (also aliased as model
).
Can a controller get data from more then one model? If so, how is this done?
Yes it is possible. Additional models can be set on a controller from a route's setupController
hook. That said in most cases you will want to use multiple controllers.
If the controller has more then one function associated with it, how do you trigger the right one within the template.
Controller functions are triggered via the handlebars {{action}}
helper. The first parameter to that helper is the name of the function to trigger. So {{action "save"}}
will trigger the controller's save
function and {{action "cancel"}}
triggers the cancel
function.
Any examples would help... I've been searching around and in most cases they deal with the simple case where there is one controller linked with one model and the controller is linked with one template.
The reason it's hard to find examples like that is because it's not a best practice. For sure it is possible to have one controller linked to multiple models or a template that uses multiple controllers but it's just not a good idea.
What happens if the template wants to use more then one controller?
Technically this could be done by using global variables but please don't. Controllers are very lightweight. Each template gets it's own controller. If a template needs data from other controllers then it's controller should make that data available. This can be done via the needs
property. See managing dependencies between controllers
{{each message in messages}}
{{message.username}}: {{message.text}}
{{/message}}
{{input valueBinding="text"}}
<button {{action send}}>Send</button>
App.ChatController = Ember.Controller.extend({
needs: ['messages', 'currentUser'],
messagesBinding: 'controllers.messages'
send: function() {
var message = App.Message.createRecord({
username: this.get('username'),
text: this.get('text')
});
message.save();
this.set('text', '');
}
})
来源:https://stackoverflow.com/questions/18500026/understanding-models-controllers-templates-with-ember-js