backbone.js 在集合上使用 fetch() 时遇到问题
警告:代码位于 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()
填充它之间存在一些细微的区别。该对象在脚本调试窗口中看起来不错,但并不令人高兴。
那么,这里发生了什么事,我是否走在正确的轨道上?
谢谢
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Fetch 是一个异步方法,这意味着当您渲染视图时,数据还没有被检索到,但是当您手动编写时,数据就在那里。执行此操作的一般方法是将 fetch 调用的重置触发器绑定到 render 方法。
您可能应该在实例化视图的下方添加您的ongs.fetch。
Fetch is an asynchronous method, this means that when you render your view, the data has not been retrieved, but when you write it manually, the data is there. The general way to do this is to bind the reset trigger that gets called by fetch to the render method.
You should probably more your songs.fetch below where you instantiate your view too.
正如 Gazler 所回答的,问题是 fetch 是异步的。如果您想使用 Gazler 的解决方案,请注意集合的
fetch
方法默认不再触发reset
事件。因此,您需要让集合显式触发reset
事件:解决此问题的另一个解决方案是使用 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/
As answered by Gazler, the problem is that
fetch
is asynchronous. If you want to use Gazler's solution, be aware that the collection'sfetch
method no longer triggers thereset
event by default. Therefore, you'll need to have the collection explicitly trigger thereset
event:Another solution to solving this is using jQuery deferreds to display the view once the results have been fetched. More one using deferreds to manage view display when fetching data asynchronously: http://davidsulc.com/blog/2013/04/01/using-jquery-promises-to-render-backbone-views-after-fetching-data/
And waiting for multiple asynchronous data sources to return: http://davidsulc.com/blog/2013/04/02/rendering-a-view-after-multiple-async-functions-return-using-promises/