Search code examples
backbone.jsviewinitialization

Backbone - How to handle element initialization for child views?


I've been using Backbone.js for a couple of months, and I ran into a dilemma recently when using backbone with one CSS frameworks.

Some of the elements from the CSS framework require some JS initializations, and these elements are part of nested views (child views). Being part of the child views, I immediately assumed that these initializations should be handled inside the child view:

app.ChildView = Backbone.View.extend({

  el: ....

  template: ...

  events: {
    ...
  },

  initialize: function() {
    ...
  },

  render: function() {
      ....

      this.$elementWithInitialization = this.$('.element');
      this.$elementWithInitialization.initialize();

      return this;
  },
});

Being a child view, this view won't be part of the DOM till its highest ancestor inserts all the child views, so its elements' initializations won't work till the outermost view finishes building the DOM. Illustrating this:

<view1>
  <view2>
    <view3></view3>
    <view3></view3>
    ...
  </view2>
  <view2>
    <view3></view3>
    <view3></view3>
    ...
  </view2>
  ...
</view1>

So, the elements in view3 can only be initialized till view1 ends inserting all its sub views. I'm just curious about what the appropriate approach for handling these elements' initializations in child views is, considering their rendering depends on their ancestors.

I can always do a selector for all these elements in the outermost view and initialize them, but I think this breaks the modularity of the views and separation of concerns. Thanks for your input.


Solution

  • You can pass a reference to the parent view (outermost view) to the children and have them listen for a ready event from the parent.

    //Child
    initialize: function(options){
      this.listenTo(options.outermostParent, 'ready', this.initCSSComponent);
    }
    
    //Outermost parent when stuff is ready and injected to DOM
    this.trigger('ready');
    

    If you have a global event emitter object you can use it as well.