remove from collection bind to remove from view
I have a backbone collection and when I remove a model from the collection, I want it to remove the item from a list in the view.
My collection is pretty basic
MyApp.Collections.CurrentEvents = Backbone.Collection.extend({ model: MyApp.Models.Event });
and in my views I have
MyApp.Views.CurrentEventItem = Backbone.View.extend({ el: 'div.current_event', initialize: function(){ event = this.model; _.bindAll(this, "remove"); MyApp.CurrentEvents.bind('remove',this.remove); //the collection holding events this.render(); }, // yeah, yeah, render stuff here remove: function(){ console.log(this); $(this.el).unbind(); $(this.el).remove(); } });
when I remove the model from the collection, it triggers the remove function, but the view is still on the page. In the console, I can see the model, but I believe the model should have an 'el', but it doesn't.
My container code is
MyApp.Views.CurrentEventsHolder = Backbone.View.extend({ el: 'div#currentHolder', initialize: function(){ MyApp.CurrentEvents = new MyApp.Collections.CurrentEvents(); MyApp.CurrentEvents.bind('new', this.add); }, add: function(){ var add_event = new MyApp.Views.CurrentEventItem(added_event); $('div#currentHolder').append(add_event.el); } });
for some reason in the add
method I can't seem to use the $(this.el)
before the append, though I'm not sure if that is the problem.
PROBLEM: MyApp.CurrentEvents.bind('remove',this.remove);
This triggers the remove()
function every time any model is deleted from the collection.
This means that anytime a model is deleted, all the CurrentEventItem
view instances will be deleted.
Now, about the view still being on the page:
It must have something to do with the way you appended/added/html-ed the view in the page. Check your other views, maybe if you have a CurrentEventsContainer
view of some sort, check your code from there because with your current code, it does delete the view, albeit, all of them though.
RECOMMENDED FIX:
change your bindings to:
this.model.bind('remove',this.remove);
and make sure that when you instantiate it, pass on the model
so that each view will have a corresponding model to it like so:
//...
addAllItem: function(){
_.each(this.collection, this.addOneItem())
},
addOneItem: function(model){
var currentEventItem = new MyApp.Views.CurrentEventItem({model:model});
//...more code..
}
//...
This makes things a lot easier to manage in my opinion.
UPDATE (from your updated question)
The reason you aren't able to use this.el
is because you haven't passed the right context into the add()
function. You need to add _.bindAll(this,'add')
in your initialize()
function to pass the right context, therefore making your this
correct, allowing you to use this.el
within the add
function. Also, change your code to this:
MyApp.CurrentEvents.bind('new', this.add, this);
this passes the right context. Also, why not use add
instead as an event?
Continuing what I said in the comments, the way you've implemented this right now will remove all the CurrentEventItem
views from the page when any of them is removed from the collection. The reason for this is the following:
MyApp.CurrentEvents.bind('remove',this.remove);
What this essentially says is, "every time the remove
event is triggered on the collection, call this.remove
." So, every time you instantiate one of these views, you're also telling the collection to remove that view when the collection triggers a remove
event. I've created a fiddle to show you the problem.
You're right that Backbone knows which model has been removed from a collection, but you're not taking advantage of that. You can do that like so:
removeFromView: function(model) {
// Check to make sure the model removed was this.model
if (model.cid === this.model.cid) {
$(this.el).unbind();
$(this.el).remove();
}
}
See how this minor adjustment changes the behavior? Check it out in action here.
If you follow this pattern, you should see the proper views being removed.
链接地址: http://www.djcxy.com/p/48314.html下一篇: 从集合中删除绑定以从视图中删除