Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to render and append sub-views in Backbone.js
    text
    copied!<p>I have a nested-View setup which can get somewhat deep in my application. There are a bunch of ways I could think of initializing, rendering and appending the sub-views, but I'm wondering what common practice is.</p> <p><em><strong>Here are a couple I've thought of:</em></strong></p> <pre><code>initialize : function () { this.subView1 = new Subview({options}); this.subView2 = new Subview({options}); }, render : function () { this.$el.html(this.template()); this.subView1.setElement('.some-el').render(); this.subView2.setElement('.some-el').render(); } </code></pre> <p><strong>Pros:</strong> You don't have to worry about maintaining the right DOM order with appending. The views are initialized early on, so there isn't as much to do all at once in the render function.</p> <p><strong>Cons:</strong> You are forced to re-delegateEvents(), which might be costly? The parent view's render function is cluttered with all of the subview rendering that needs to happen? You don't have the ability to set the <code>tagName</code> of the elements, so the template needs to maintain the correct tagNames.</p> <p><em><strong>Another way:</em></strong></p> <pre><code>initialize : function () { }, render : function () { this.$el.empty(); this.subView1 = new Subview({options}); this.subView2 = new Subview({options}); this.$el.append(this.subView1.render().el, this.subView2.render().el); } </code></pre> <p><strong>Pros:</strong> You don't have to re-delegate events. You don't need a template that just contains empty placeholders and your tagName's are back to being defined by the view.</p> <p><strong>Cons:</strong> You now have to make sure to append things in the right order. The parent view's render is still cluttered by the subview rendering.</p> <p>With an <code>onRender</code> event:</p> <pre><code>initialize : function () { this.on('render', this.onRender); this.subView1 = new Subview({options}); this.subView2 = new Subview({options}); }, render : function () { this.$el.html(this.template); //other stuff return this.trigger('render'); }, onRender : function () { this.subView1.setElement('.some-el').render(); this.subView2.setElement('.some-el').render(); } </code></pre> <p><strong>Pros:</strong> The subview logic is now separated from the view's <code>render()</code> method.</p> <p>With an <code>onRender</code> event:</p> <pre><code>initialize : function () { this.on('render', this.onRender); }, render : function () { this.$el.html(this.template); //other stuff return this.trigger('render'); }, onRender : function () { this.subView1 = new Subview(); this.subView2 = new Subview(); this.subView1.setElement('.some-el').render(); this.subView2.setElement('.some-el').render(); } </code></pre> <p>I've kind of mix and matched a bunch of different practices across all of these examples (so sorry about that) but what are the ones that you would keep or add? and what would you not do?</p> <p>Summary of practices:</p> <ul> <li>Instantiate subviews in <code>initialize</code> or in <code>render</code>?</li> <li>Perform all sub-view rendering logic in <code>render</code> or in <code>onRender</code>?</li> <li>Use <code>setElement</code> or <code>append/appendTo</code>?</li> </ul>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload