Reputation: 2614
I'm currently using "ember-1.0.0-rc.7.js" to manage the persistence and data storage for my ember application.
user.js
App.User = DS.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string'),
category: DS.attr('string'),
status: DS.attr('string'),
position: DS.attr('string'),
fullName: function()
{
return '%@ %@'.fmt(this.get('firstName'), this.get('lastName'))
}.property('firstName', 'lastName')
});
App.User.FIXTURES =
[
{
id: 1,
firstName: 'Derek',
lastName: "H",
category: "admin",
status: "offline",
position: "3232"
},
{
id: 2,
firstName: 'Jim',
lastName: "H",
category: "admin",
status: "online",
position: "322"
}
];
UserListController.js
App.UserListController = Ember.ArrayController.create({
content: [],
users: App.User.find()
});
store.js
App.Store = DS.Store.extend({
revision: 12,
adapter: 'DS.FixtureAdapter'
});
From the above, I assumed that App.User.find() would return me all the users. However, I get the following error:
Error From Firebug:
Your application does not have a 'Store' property defined. Attempts to call 'find' on model classes will fail. Please provide one as with 'YourAppName.Store = DS.Store.extend()'
TypeError: store is undefined
The message doesn't make sense, but the store is defined for App. If the store was not defined, then the below code would not work.
In the below code, I call App.User.find() within the context of the route and it works.
router.js
Bib.Router.map(function () {
this.resource('index', { path: '/' });
});
App.IndexRoute = Ember.Route.extend({
model: function () {
return ['a','b', 'c' ];
},
renderTemplate: function () {
this.render();
this.render('userList', { outlet: 'userList', into: 'application', controller: App.UserListController });//render the list in list outlet
},
setupController: function (controller, model)
{
controller.set('menu', model);
controller.set('test', App.User.find());
}
});
In the index.html
<script type="text/x-handlebars" id="userList" data-template-name="userList">
{{#each controller}}
{{firstName}}
{{/each}}
</script>
I want the contoller there to represent the UserListController and have it have a reference to the User Model. Keep in mind I can't hook this up in the route since I only have one route for this application.
I believe this is due to the context in which I'm making the call. In other words, using it within the Controller.I'm probably not understanding a fundamental concept how controllers and models are related.
Any advice appreciated, Thanks, D
Upvotes: 0
Views: 9317
Reputation: 330
It is possible to make find
calls within controllers. However, that isn't quite what is happening in UserListController.js
.
You are calling Ember.ArrayController.create
instead of Ember.ArrayController.extend
. That is, you are creating a global instance of an ArrayController
rather than defining a new class of controller.
At the time this find
call is made, when UserListController.js
is evaluated, the store you have defined has not yet been setup.
You can see this by removing this code and then evaluating it in your browser console once your app has started up.
However, creating a global controller and manually setting data on it is a pattern that is discouraged. The common pattern in Ember apps is to create controller classes which are instantiated and then populated with data by routes.
For example:
App.Router.map(function () {
this.resource('user', { path: '/' });
});
App.UserIndexRoute = Ember.Route.extend({
model: function () {
return App.User.find();
}
});
This will automatically create a UserIndexController
which is an Ember.ArrayController
and set its content
to App.User.find()
.
Now, that is a simplified example and not what you are trying to do. It looks like you want to render a list of users, stored in a UserListController
, into an outlet on your main template.
To do this you would need something like:
App.Router.map(function() {
// you don't need to create an index resource
// an IndexRoute is created by default
});
App.UserListController = Ember.ArrayController.extend();
App.IndexRoute = Ember.Route.extend({
model: function() {
return ['a', 'b', 'c'];
},
setupController: function (controller, model) {
controller.set('menu', model);
this.controllerFor('userList').set('content', App.User.find());
},
renderTemplate: function() {
var controller = this.controllerFor('userList');
this.render();
this.render('userList', {controller: controller});
}
});
Upvotes: 4
Reputation: 8574
The problem is probably being caused by the users: App.User.find()
line. The call to find()
is probably being called at the time that the model is first evaluated, which is probably before your store is defined. The Ember Way (tm) is to use the route to set up the model for your controller. Whatever is returned from the model
method in your route will be set to the 'content'
property in your controller.
App.UserListRoute = Ember.Route.extend({
model: function() {
return App.User.find();
}
});
App.UserListController = Ember.ArrayController.create({
// you don't need anything here
// the model from the route will be set to 'content'
});
If you need the 'content'
property to be blank, and you need the list to live in the 'users'
property you could do this.
App.UserListRoute = Ember.Route.extend({
setupController: function() {
this.controller.set('content',[]);
this.controller.set('users', App.User.find());
}
});
App.UserListController = Ember.ArrayController.create({
// still don't need anything here
});
Upvotes: 2