Reputation: 581
I'm using Backbone and I have the following model and collection
App.Models.Person = Backbone.Model.extend({
});
App.Collections.People = Backbone.Collection.extend({
model: App.Models.Person,
url: 'api/people',
});
However what I'm struggling on is the best way to render this collection. Here's how I've done it so far which works but doesn't seem to be the most elegant solution
App.Views.PeopleView = Backbone.View.extend({
el: $(".people"),
initialize: function () {
this.collection = new App.Collections.People();
//This seems like a bad way to do it?
var that = this;
this.collection.fetch({success: function(){
that.render();
}});
},
render: function () {
var that = this;
_.each(this.collection.models, function (item) {
that.renderPerson(item);
}, this);
},
I'm fairly new to Backbone but have to assign this
to a different variable to I use it inside of the success function just seems like a bad way of doing things? Any help on best practices would be appreciated.
Upvotes: 0
Views: 76
Reputation: 2092
Backbone allows you to register for events that you can react to. When the collection is synchronized with the server, it will always fire the sync
event. You can choose to listen for that event and call any given method. For instance ...
initialize: function () {
this.collection = new App.Collections.People();
this.listenTo(this.collection, "sync", this.render);
// Fetch the initial state of the collection
this.collection.fetch();
}
... will set up your collection so that it would always call this.render()
whenever sync
occurs.
The docs on Backbone Events are succinct but pretty good. Keep in mind a few things:
listenTo
or on
) changes how you provide the context of the called function. listenTo
, for instance, will use the current context automatically; on
will not. This piece of the docs explains it pretty well.listenTo
to connect them in the first place; then when destroying the view you can just call view.stopListening()
.For rendering, there are a lots of suggestions for how to do it. Generally having a view to render each individual model is one way. You can also use Backbone.Collection#each
to iterate over the models and control the scope of the iterating function. For instance:
render: function() {
this.collection.each(function(model) {
var view = new App.Collections.PersonView({ model: model });
view.render();
this.$el.append(view.$el);
}, this);
}
Note the second argument to .each
specifies the scope of the iterator. (Again, have a look at the docs on controlling scope. If you'd rather have a framework help out with the rendering, check out Marionette's CollectionView and ItemView.
Upvotes: 1
Reputation: 21
If your view is supposed to just render the collection you can send the collection to temnplate and iterate through in template, otherwise you can create another subView for that purpose or send the individual models of the collection to another subview and append to the container, hope it was helpful.
Upvotes: 0