Whoa there nellie. Complexity ahoy.<p>Why would you want to have a view that dumps out its HTML as a string? If a string of HTML is all you want, don't use a view, just use a template.<p>But putting that aside for a second ... for this particular example, how about this:<p><pre><code> render: ->
this.$el.html JST["table_view_template"]()
tbody = this.$el('tbody')
for person in this.collection.models
view = new TableRowView model: person
tbody.append view.render().el
</code></pre>
... or if you were in earnest about only needing the raw HTML from the sub-view, how about just rendering the row templates within the table template, making your render function as simple as this:<p><pre><code> render: ->
this.$el.html this.template people: this.collection</code></pre>
How is the performance when each row gets its own object instantiated, its own template loaded, and its own events attached? What happens when you have 1000+ rows in a scrollable/sortable/filterable table? I tried nested views approach but the performance was lacking in slower PCs when the row count was high.<p>What I prefer to do is the following:<p><pre><code> class Example.Views.TableView extends Backbone.View
events:
'click td': 'clicked'
rowHtml: ->
x = []
p = $('#person_row').html()
for person in @collection.models
x.push(_.template(p, person))
x.join('')
clicked: (e) ->
id = $(e.target).parents('tr').attr('id')
# handle action for row id
render: ->
# render self view including rowHTML
</code></pre>
The template is loaded just once into a variable and filled in each iteration. Only one set of events is attached to the DOM. Only one call is made to DOM to create all the rows, one string merged from HTML array. I still get the benefit of view and subview templates, without the constructor for subview objects being called 1000 times when all I need is the <tr> HTML x 1000.
This is getting way too many votes for what amounts to bad advice. I think you should keep subview rendering methods out of your templates (i.e. keep your templates "dumb"). You can just create placeholder elements in the template, and then pass the placeholder element to the subview constructor. Or you can just append a list of collection-based subviews to a single container element.<p>You should be able to write Backbone apps without resorting to stuff like $("#row_#{@model.id}")<p>And for an example, here's a gist <a href="https://gist.github.com/2931491" rel="nofollow">https://gist.github.com/2931491</a>
Something I haven't been able to understand: why does almost every Backbone project generate <i>and</i> update views by applying templates to generate new HTML strings, and then new DOM fragments?<p>Wouldn't it be much more efficient to create a view just <i>once</i> by setting innerHTML, and then update it using the DOM (setting attributes, classes, innerText, etc.)? Surely this would reduce GC pressure, reflow events, and so on.<p>I'm seeing "use templates for everything" in most Backbone tutorials and projects, and I can't help but think that this is an anti-pattern.
A lot of people are finding out that views are the hardest thing to do - especially with Backbone. The problem is that views are tightly coupled to the model so it's hard to build them up. I just wrote <a href="http://modernjavascript.blogspot.com/2012/06/v-in-mvc.html" rel="nofollow">http://modernjavascript.blogspot.com/2012/06/v-in-mvc.html</a> for another post but believe that it could be helpful in this situation. You'd need to actually write a Backbone.controller class and move the logic in to there but then you could create a whole lot of Backbone.Views that were generic and could be hooked up through the Control (I'd also like to see a Backbone.MultiView or something that could take several views in and then re-emit the changes and allow people to add in several small component views in to a large view either for a collection or a model.
Personally, I've been more inspired by EmberJS as a template approach. I've gotten the basics working and up and available on github. <a href="https://github.com/koblas/distal" rel="nofollow">https://github.com/koblas/distal</a><p>While I don't yet have a fancy blog post about the system and why it's "better" I would be interested if people think there is some core value in this style of View abstraction for Backbone.
Check out the Collection GridView in luca. <a href="http://datapimp.com/luca/" rel="nofollow">http://datapimp.com/luca/</a>. Source: <a href="https://github.com/datapimp/luca/blob/development-tools/src/components/grid_view.coffee" rel="nofollow">https://github.com/datapimp/luca/blob/development-tools/src/...</a>
This is the pattern I go with: <a href="https://gist.github.com/2931439" rel="nofollow">https://gist.github.com/2931439</a><p>It decouples a little more logic from the template, and I think it adheres very closely with some things Backbone expects (like passing through the entire el to the DOM).
Why not just append all of the views in TableView render, and then have TableRowView set its own ID in its initialize or render method?<p>I think that would be more concise and straightforward.