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
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
anderror
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".