Question

I have a Rails project with Backbone.js and HAML as client side templating language.

in file app/assets/views/meeting.coffee:

class window.MeetingIndex extends Backbone.View

  template: JST['meeting/index']

  render: ->
    @collection.fetch()
    @$el.html(@template(collection: @collection))
    this

in file app/assets/javascripts/templates/meeting/index.hamlc

- console.log(@collection.length) # prints 0 in console
- console.log(@collection.models) # prints [] in console
- console.log(@collection.at(0))  # prints undefined in console
- window.x =  @collection

if I go to the browser console I get:

x.length # returns 2
x.models # returns [Meeting, Meeting]
x.at(0)  # returns Meeting object

If I can access @collection variable in .hamlc file, because I am assigning it to window.x. Why can't I access the @collection items from the .hamlc file?

I need something like

- for model in @collection.models
  %p= model.get('landlord_id')
  %p= model.get('tenant_id')
  %p= model.get('at')

to work

Was it helpful?

Solution

The Collection#fetch method is asynchronous (i.e. it is an AJAX call behind the curtains) so @collection.fetch() hasn't gotten anything back from the server when you try to use it in your view. However:

The options hash takes success and error callbacks which will be passed (collection, response) as arguments. When the model data returns from the server, the collection will reset.

So you can use the callbacks:

render: ->
  @collection.fetch(
    success: (collection, response) =>
      @$el.html(@template(collection: @collection))
  @

Or you can bind the view's render to the collection's reset event:

class window.MeetingIndex extends Backbone.View
  template: JST['meeting/index']
  initialize: ->
    @collection.on('reset', @render)
    @collection.fetch()
  render: =>
    @$el.html(@template(collection: @collection))
    @

Then the fetch call in the view's initialize would indirectly trigger the proper render call when it gets something back from the server. This approach works best if your template knows what to do with an empty collection, perhaps it could detect an empty collection and display a "loading" message or just say "nothing's here yet".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top