ChatGPT解决这个技术问题 Extra ChatGPT

Destroy or remove a view in Backbone.js

I'm currently trying to implement a destroy/remove method for views but I can't get a generic solution to work for all my views.

I was hoping there would be an event to attach to the controller, so that when a new request comes through it destroys previous views then loads the new ones.

Is there any way to do this without having to build a remove function for each view?

Could you give an example of what your view eco-system is? Your question makes me think there are many views on the page at once. I can't quite visualize what you are trying to do and thus can't offer an answer that might be what you need.

a
alex

I had to be absolutely sure the view was not just removed from DOM but also completely unbound from events.

destroy_view: function() {

    // COMPLETELY UNBIND THE VIEW
    this.undelegateEvents();

    this.$el.removeData().unbind(); 

    // Remove view from DOM
    this.remove();  
    Backbone.View.prototype.remove.call(this);

}

Seemed like overkill to me, but other approaches did not completely do the trick.


for what I've seen, this.remove() should call jQuery's remove, which should remove the element from the DOM but also remove data and events attached to it. So I guess the call to undelegateEvents and removeData shouldn't be necessary... Am I right?
@opensas Events were persisting past the this.remove() despite the element being removed from the DOM. this.undelegateEvents() was needed for all the events to unbind. As I said, it felt like overkill, but it did the trick.
I like it. Eventhough you should be using this.$el instead of $(this.el) ;)
+1 for a good answer to my problem, +1 for writing your first answer :)
My view is not getting re-rendered on destroying and creating it again. Is it because of this.remove()?
j
joshvermaire

Without knowing all the information... You could bind a reset trigger to your model or controller:

this.bind("reset", this.updateView);

and when you want to reset the views, trigger a reset.

For your callback, do something like:

updateView: function() {
  view.remove();
  view.render();
};

I don't think this is right. The View's remove function just remove's that view's element from the DOM (see here). I think this guy wants to remove the view object entirely.
this.remove() ends up calling jquery's remove(), which also removes data and events... Nevertheless I think you also have to call this.undelegateEvents to unbind from other events, like custom events or changes to the model..
this.remove() calls this.stopListening() and this.$el.remove(). The first removes all event listeners added using this.listenTo(...). The second removes all event listeners add using jQuery. Between the two, you should be covered unless you used some other means of adding event listeners. So this answer is correct and gets +1 from me.
B
Bassam Mehanni

I know I am late to the party, but hopefully this will be useful for someone else. If you are using backbone v0.9.9+, you could use, listenTo and stopListening

initialize: function () {
    this.listenTo(this.model, 'change', this.render);
    this.listenTo(this.model, 'destroy', this.remove);
}

stopListening is called automatically by remove. You can read more here and here


J
JT703

This is what I've been using. Haven't seen any issues.

destroy: function(){
  this.remove();
  this.unbind();
}

D
Dre

According to current Backbone documentation....

view.remove()

Removes a view and its el from the DOM, and calls stopListening to remove any bound events that the view has listenTo'd.


C
Chhorn Ponleu

I think this should work

destroyView : function () {
    this.$el.remove();
}

Have to kill listeners also with this.stopListening() and then return this for good measure
D
Deot

You could use the way to solve the problem!

initialize:function(){
    this.trigger('remove-compnents-cart');
    var _this = this;
    Backbone.View.prototype.on('remove-compnents-cart',function(){
        //Backbone.View.prototype.remove;
        Backbone.View.prototype.off();
        _this.undelegateEvents();
    })
}

Another way:Create a global variable,like this:_global.routerList

initialize:function(){
    this.routerName = 'home';
    _global.routerList.push(this);
}
/*remove it in memory*/
for (var i=0;i<_global.routerList.length;i++){
    Backbone.View.prototype.remove.call(_global.routerList[i]);
}

The first approach worked for me, I ran into a similar problem with views ghosting and the events were firing multiple times when each view was being recreated when you submitted the form