4

I need to run a layout script as soon as my views are inserted into the DOM. So...

$(".widgets").append(widgets.render().el)
$(".widgets .dashboard").isotope # <-- This needs to be called whenever new widgets are inserted

The problem is I have to insert new widgets a few different views and re-call this script a few different places, which is not DRY. I am wondering how I can define the isotope in the View class.

Would it be a good idea to define an event listener to watch for append into the ".widgets" and to run the script? Is there a built in way of building views that are smart about when they are added to the DOM?

(For that matter, it would be also useful to define a callback for when a View is removed from the DOM.)

picardo
  • 24,530
  • 33
  • 104
  • 151
  • Possible dupe of http://stackoverflow.com/questions/1324647/can-javascript-listen-for-ondomchange-on-every-dom-elements – tkone Mar 06 '12 at 00:29
  • I don't think it's a duplicate. I'm looking for a solution rooted in Backbone, but thanks for that link. – picardo Mar 06 '12 at 00:35
  • Well, the solution is that you attach a listener in your view that calls `this.isotope` upon insertion. So like you append(widget.render().el) where it needs to go. Widget's initialize function binds the `isotope` method to the DOM insert event. That's about as rooted in backbone as you can get especially since backbone doesn't have a native facility for that. I say it's a dupe because what you're looking to do is "do something when the Dom is modified". Regardless of your framework, that's the essence boiled down (unless I missed something) – tkone Mar 06 '12 at 13:12

2 Answers2

0

use:

var self = this;    
this.$el.on('DOMNodeInserted', function(evt){   
self.isotope();
$(evt.target ).stopPropagation();
})
norbertas.gaulia
  • 2,033
  • 3
  • 18
  • 19
0

How about calling the isotope each time the view is rendered? You'll need to be careful to call render() only after the widget is injected, but this ought to take care of your problem:

 //in Backbone.view.extend({
   initialize: function() {
     // fix context for `this`
     _.bindAll(this);
   },
   render: function() {
     // .. do rendering..
     this.isotope();
     return this;
   }
 // }) // end .extend
rjz
  • 16,182
  • 3
  • 36
  • 35
  • 1
    I tried that. The problem is the HTML won't be in the DOM until it's been appended by the parent view. – picardo Mar 06 '12 at 00:32
  • Might need to break the insertion into two steps? `widgets.render(); $(".widgets").append(widgets.el)` – rjz Mar 06 '12 at 00:38