警告:代码在Coffeescript中。我希望没问题。
我有一个模型,Song
,一个集合Songs
和一个视图SongsView
。这是:
SONG_TEMPLATE = '''
<table>
{{#if songs.length }}
{{#each songs}}
<tr><td>{{ this.name }}</td><td>{{ this.duration }}</td></tr>
{{/each}}
{{/if}}
</table>
'''
$ ->
class Song extends Backbone.Model
parse: (response) ->
console.log "model parsing #{response}"
#
class Songs extends Backbone.Collection
initialize: ->
@model = Song
@url = "/songs/data"
parse: (response) ->
console.log "collection parsing"
console.log response
# This works. The JSON here was grabbed right out of the XHR response I got from the server and pasted into my code.
songs = new Songs(
[
{"name":"Stray Cat Strut","rating":4,"duration":3},
{"name":"Chinatown","rating":2,"duration":4.2},
{"name":"Sultans of Swing","rating":3,"duration":5.4},
{"name":"Pride & Joy","rating":3,"duration":3}
]
)
# This fails. It should be exactly the same as the above code, and indeed, the collection parsing takes place.
# However, the view renders nothing.
# songs = new Songs
# songs.fetch()
class SongsView extends Backbone.View
initialize: ->
@model = Song
@render()
render: =>
console.log "render"
console.log @collection
template = Handlebars.compile(SONG_TEMPLATE)
@template = template(songs: @collection.toJSON())
console.log "template: #{@template}"
$('#song-list').html @template
songView = new SongsView(collection: songs)
我遇到的问题是,在从JSON字符串初始化songs
和允许主干使用fetch()
填充它之间存在一些细微差别。该对象在脚本调试窗口中看起来没问题,但没有快乐。
那么,这里发生了什么,我是否走上正轨?
由于
答案 0 :(得分:3)
Fetch是一种异步方法,这意味着当您渲染视图时,尚未检索到数据,但是当您手动编写数据时,数据就在那里。执行此操作的一般方法是将fetch调用的重置触发器绑定到render方法。
class SongsView extends Backbone.View
initialize: ->
@model = Song
@collection.bind("reset", @render)
render: =>
console.log "render"
console.log @collection
template = Handlebars.compile(SONG_TEMPLATE)
@template = template(songs: @collection.toJSON())
console.log "template: #{@template}"
$('#song-list').html @template
你可能应该在你实例化你的视图的地方找到更多你的歌曲。
答案 1 :(得分:0)
正如Gazler所回答的,问题是fetch
是异步的。如果您想使用Gazler的解决方案,请注意,默认情况下,集合的fetch
方法不再触发reset
事件。因此,您需要让集合明确触发reset
事件:
my_collection.fetch({reset: true})
解决此问题的另一个解决方案是使用jQuery deferreds在获取结果后显示视图。在异步获取数据时,有更多人使用延迟来管理视图显示:http://davidsulc.com/blog/2013/04/01/using-jquery-promises-to-render-backbone-views-after-fetching-data/
等待多个异步数据源返回:http://davidsulc.com/blog/2013/04/02/rendering-a-view-after-multiple-async-functions-return-using-promises/