Reputation: 8937
So I've got a pretty simple backbone app with a model, a collection, and a couple of views. I'm fetching the actual data from the server by doing a collection.fetch() at page load.
My problem is that one of my views is a "detail" view, and I want to bind it to a particular model - but I don't have the model yet when the page loads. My code looks a lot like this:
window.App = {
Models: {},
Collections: {},
Views: {},
Routers: {}
}
App.Models.Person = Backbone.Model.extend({
urlRoot: '/api/people'
});
App.Collections.People = Backbone.Collection.extend({
model: App.Models.Person,
url: '/api/people'
});
people = new App.Collections.People()
App.Views.List = Backbone.View.extend({
initialize: function() {
this.collection.bind('reset', this.render());
},
render: function() {
$(this.el).html("We've got " + this.collection.length + " models." )
}
});
listView = new App.Views.List({collection: people})
App.Views.Detail = Backbone.View.extend({
initialize: function() {
this.model.bind('change', this.render());
},
render: function() {
$(this.el).html("Model goes here!")
}
});
App.Routers.Main = Backbone.Router.extend({
routes: {
'/people': 'list',
'/people/:id': 'detail'
},
list: function() {
listView.render();
},
detail: function(id) {
detailView = new App.Views.Detail({model: people.get(id)})
detailView.render()
}
})
main = new App.Routers.Main();
Backbone.history.start();
people.fetch();
But if I start with the detail route active, the people
collection is empty, so people.get(id)
doesn't return anything, so my new view has this.model
undefined, and won't let me bind any events relating to it. The error is:
Uncaught TypeError: Cannot call method 'bind' of undefined
If I start with the list route active, then by the time I click on an item to bring up the detail view people
is populated, so everything works.
What's the right way to bind model-related events for a "detail" view when you're fetching the data after page load?
Upvotes: 0
Views: 655
Reputation: 1703
You have a part of the answer here: Backbone.js Collections not applying Models (using Code Igniter)
Indeed, you need to wait that people.fetch
finishes its ajax request before to call Backbone.history.start();
and trigger the actual route.
Your code should look like:
// [...]
main = new App.Routers.Main();
peoples.fetch({
success: function (collection, response) {
// The collection is filled, trigger the route
Backbone.history.start();
}
});
You can add a loader on the page and hide it when the collection is loaded.
Upvotes: 1