I have a view for individual Customer models that takes a customer and collection of customers on construction. The requirement of the customer model makes sense -- it is a view for a customer. The requirement of the collection ... I'm not sure if that is a smell or not and would love feedback!
The reason it needs the collection is so that a button in the view can remove the customer from the customers collection and that the view can also listen to collection remove events to see if it has to be unrendered (it was successfully removed from the collection).
var CustomerView = Backbone.View.extend({
events: {
'click button.delete': 'remove'
},
initialize: function() {
_.bindAll(this, 'render', 'unrender', 'remove', 'removed');
this.model.bind('change', this.render);
this.collection.bind('remove', this.removed);
}
// render / unrender removed for brevity
remove: function () {
this.collection.remove(this.model);
},
removed: function (customer) {
if (this.model === customer) {
this.unrender();
}
}
});
Here is how the view is created:
var CustomersView = Backbone.View.extend({
initialize: function () {
_.bindAll(this, 'appendCustomer');
this.model.customers.bind('add', this.appendCustomer);
},
appendCustomer: fu开发者_如何学Gonction (customer) {
var customerView = new CustomerView({
model: customer,
collection: this.model.customers
});
$(this.el).append(customerView.render().el);
}
});
I was thinking I could somehow wire up the CustomerView in this appendCustomer method instead of simply giving the customers collection to the CustomerView wholesale.
Thoughts? Thanks!
If you are adding these models through the collection, you may want to investigate using the model's collection property. This would take the place of the customers association that you plan to give it.
Given the above, you may only need to pass the model into the view. And if you need to access the collection in the template or otherwise, its just 'this.model.collection'.
Also, you can then simply call the 'destroy' method on the model and it will be removed from the collection. You would then use the same event binding strategy you have now except with this built-in collection.
You just have to think in events
instead of explicit method calls.
In this example I'm using a custom event.
// simplified code
var CustomerView = Backbone.View.extend({
events: {
'click button.delete': 'remove'
},
initialize: function() {
this.model.bind( "app:remove", this.removed );
},
remove: function () {
this.model.trigger( "app:remove" );
},
removed: function (customer) {
this.unrender();
}
});
// The collection it self removes the model
var CustomersCollection = Backbone.Collection.extend({
initialize: function(){
this.on( "app:remove", this.remove )
}
});
精彩评论