Reputation: 4668
i know that backbone doc says fetch should not be used to populate collections on page load,and i kind of figure out why:
var appCollection = Backbone.Collection.extend({
model:appModel,
url:'api/app',
initialize:function(){
this.fetch();
},
});
var homeView = Backbone.View.extend({
el:'#content',
initialize:function(){
this.collection = new appCollection(appModel)
this.render()
},
render: function () {
var that = this;
alert(1);
_.each(this.collection.models, function (item) {
that.renderApp(item);
}, this);
},
renderApp: function (item) {
var appview = new appView({
model: item
});
this.$el.append(appview.render().el);
}
})
var home = new homeView();
the homeview.render function actually get called before the collection fetched, so when i remove the alert(1); my app wont get rendered, and i get some error says "appname"(template) is undefined.
any idea how to do this?
the fetch method comes really handy and i dont mind to wait for a few second,actually i was intend to show a progress bar indicating that the page is initializing because i got lots of other thing to download,so is it possible to use fetch and when the collection is actually fetched then tha code continue to run???
Upvotes: 4
Views: 4672
Reputation: 13105
Let's take this from the beginning:
var appCollection = Backbone.Collection.extend({
model:appModel,
url:'api/app',
initialize:function(){
this.fetch();
},
});
I would avoid fetching inside initialize
. Creating an instance of an appCollection should not necessitate fetching. So use:
var appCollection = Backbone.Collection.extend({
model:appModel,
url:'api/app',
});
Then,
var homeView = Backbone.View.extend({
el:'#content',
initialize:function(){
this.collection = new appCollection(appModel)
this.render()
},
render: function () {
var that = this, p;
console.log('fetching...');
p = this.collection.fetch();
p.done(function () {
console.log('fetched!');
_.each(that.collection.models, function (item) {
that.renderApp(item);
}, that);
});
},
renderApp: function (item) {
var appview = new appView({
model: item
});
this.$el.append(appview.render().el);
}
})
var home = new homeView();
This allows you to render your homeView and when the collection has been fetched, it will render its models. If you do not understand what p.done
does, have a look at jQuery's Deferred. In brief an ajax request returns a promise. When the promise is fulfilled (i.e. your collection is fetched) the deferred fires and whatever function you specified in .done()
will execute.
Use the points where I console.log
to give feedback on the progress.
Upvotes: 13