Backbone.js + pens each

I am trying to convert Ryan RailsCast to Backbone.js to work with Handlebars and I am stuck in a simple problem.

It seems I can not iterate over the JSON array and show the result. I use these gems in my gemfile

gem 'backbone-on-rails' gem 'handlebars_assets' 

In my index.jst.hbs , I have the following:

 {{entries.length}} <ul> {{#each entries.models}} <li>{{name}}</li> {{/each}} </ul> 

The API call seems to work, as you can see in score 7 in the screenshot. enter image description here

However, the contents of each model are not displayed. Here's a view of View (index.js.coffee) and JSON.

  class Raffler.Views.EntriesIndex extends Backbone.View template: JST['entries/index'] initialize: -> #triggered when view gets created, listen to 'reset' event, then re-@render , pass 'this' for context binding @collection.on('reset', @render, this) render: -> $(@el).html(@template(entries: @collection)) this 

JSON:

 [ { "created_at":"2012-06-28T18:54:28Z", "id":1, "name":"Matz", "updated_at":"2012-06-28T18:54:28Z", "winner":null }, { "created_at":"2012-06-28T18:54:28Z", "id":2, "name":"Yehuda Katz", "updated_at":"2012-06-28T18:54:28Z", "winner":null }, { "created_at":"2012-06-28T18:54:28Z", "id":3, "name":"DHH", "updated_at":"2012-06-28T18:54:28Z", "winner":null }, { "created_at":"2012-06-28T18:54:28Z", "id":4, "name":"Jose Valim", "updated_at":"2012-06-28T18:54:28Z", "winner":null }, { "created_at":"2012-06-28T18:54:29Z", "id":5, "name":"Dr Nic", "updated_at":"2012-06-28T18:54:29Z", "winner":null }, { "created_at":"2012-06-28T18:54:29Z", "id":6, "name":"John Nunemaker", "updated_at":"2012-06-28T18:54:29Z", "winner":null }, { "created_at":"2012-06-28T18:54:29Z", "id":7, "name":"Aaron Patterson", "updated_at":"2012-06-28T18:54:29Z", "winner":null } ] 
+7
source share
1 answer

Your @collection is supposedly Backbone.Collection . Pens will see it as an array of some type, so {{entries.length}} works as expected, and {{#each entries.models}} repeats the correct number of times; however, Handlebars does not know what to do with the Backbone.Model that are inside @collection.models .

Convert @collection to raw data with toJSON , Handlebars knows what to do with simple JavaScript arrays and objects:

 render: -> @$el.html(@template(entries: @collection.toJSON())) @ 

And then tweak your template to see only entries , not entries.models :

 <ul> {{#each entries}} <li>{{name}}</li> {{/each}} </ul> 

Demo: http://jsfiddle.net/ambiguous/tKna3/

A general rule with Backbone is to pass model.toJSON() or collection.toJSON() to your templates so that they do not know about Backbone methods (e.g. get ) and that your templates do not accidentally change your models and collections.

+11
source

All Articles