Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Backbone events on replacing html does not work?

If I store view in window.myView variable, render it, then call in javascript console:

$('#container').html('')

and then call:

$('#container').html(window.myView.$el)

Bound events will stop working.

I'm pretty sure that is supposed to be so, but:

  • why exactly it works this way?
  • how to re-render subpart of view w/o losing event bindings?
  • why calling myView.render() won't lose event bindings?

Update:

Found this article. Is that the reason?

Make sure jQuery isn’t unloading your events when you don’t want it to

If you are building an app where you create views on the fly and attach/remove them to the dom, you may have a problem. Everytime you remove a view from the dom, jQuery unloads all the events. So you can’t have a reference to a view and remove it from the dom and then re-attach it later. All your events would have been unloaded. If you wanna keep the views around, a better idea is to hide them using display:none. However, you should not abuse this and recycle views that you are not going to use for a while (and prevent memory leaks).

like image 942
Arnis Lapsa Avatar asked Feb 21 '12 20:02

Arnis Lapsa


1 Answers

jQuery empty, html and remove events are cleaning up all the jquery event and data bindings to prevent memory leaks (you can check jQuery source code for cleanData method to figure out more - it's an undocumented method)

view.render() doesn't remove the events because Backbone view events are bound using event delegation and are bound to the view's el rather then directly to the elements in the view.

If you want to reuse your views you can remove them using the jQuery detach method which keeps all the events and data bound though you have to watch out not to produce memory leaks this way. (jquery detach docs)

If you want to go the first way you can always rebind the Backbone events easily using the Backbone.View delegateEvents method. (backbone doc)

ps. it's also cleaner and more optimal to use jQuery .empty() rather then .html('') as jQuery html method always calls empty first to clean up all the events and data first before it inserts new html. Also never mix jquery and native DOM innerHTML as it might produce memory leaks cause of not cleaned up jQuery events/data

like image 124
Tom Tu Avatar answered Oct 30 '22 03:10

Tom Tu