Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>This is a perennial problem with Backbone and, in my experience, there's not really a satisfying answer to this question. I share your frustration, especially since there is so little guidance despite how common this use case is. That said, I usually go with something akin to your second example.</p> <p>First of all, I would dismiss out of hand anything that requires you to re-delegate events. Backbone's event-driven view model is one of its most crucial components, and to lose that functionality simply because your application is non-trivial would leave a bad taste in any programmer's mouth. So scratch number one.</p> <p>Regarding your third example, I think it's just an end-run around the conventional rendering practice and doesn't add much meaning. Perhaps if you're doing actual event triggering (i.e., not a contrived "<code>onRender</code>" event), it would be worth just binding those events to <code>render</code> itself. If you find <code>render</code> becoming unwieldy and complex, you have too few subviews.</p> <p>Back to your second example, which is probably the lesser of the three evils. Here is example code lifted from <a href="http://recipeswithbackbone.com/" rel="noreferrer"><em>Recipes With Backbone</em></a>, found on page 42 of my PDF edition:</p> <pre><code>... render: function() { $(this.el).html(this.template()); this.addAll(); return this; }, addAll: function() { this.collection.each(this.addOne); }, addOne: function(model) { view = new Views.Appointment({model: model}); view.render(); $(this.el).append(view.el); model.bind('remove', view.remove); } </code></pre> <p>This is only a slightly more sophisticated setup than your second example: they specifiy a set of functions, <code>addAll</code> and <code>addOne</code>, that do the dirty work. I think this approach is workable (and I certainly use it); but it still leaves a bizarre aftertaste. (Pardon all these tongue metaphors.)</p> <p>To your point on appending in the right order: if you're strictly appending, sure, that's a limitation. But make sure you consider all possible templating schemes. Perhaps you'd actually like a placeholder element (e.g., an empty <code>div</code> or <code>ul</code>) that you can then <a href="http://api.jquery.com/replaceWith/" rel="noreferrer"><code>replaceWith</code></a> a new (DOM) element that holds the appropriate subviews. Appending isn't the only solution, and you can certainly get around the ordering problem if you care about it that much, but I would imagine you have a design issue if it is tripping you up. Remember, subviews can have subviews, and they should if it's appropriate. That way, you have a rather tree-like structure, which is quite nice: each subview adds all its subviews, in order, before the parent view adds another, and so on.</p> <p>Unfortunately, solution #2 is probably the best you can hope for using out-of-the-box Backbone. If you're interested in checking out third-party libraries, one that I have looked into (but haven't actually had any time to play with yet) is <a href="https://github.com/tbranyen/backbone.layoutmanager" rel="noreferrer">Backbone.LayoutManager</a>, which seems to have a healthier method of adding subviews. However, even they have had <a href="https://github.com/tbranyen/backbone.layoutmanager/issues/19" rel="noreferrer">recent debates</a> on similar issues to these.</p>
 

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