2012-07-19 66 views
0

有点古怪的一...Backbone.js的不通过收集迭代

我有收集:

class Store.Collections.Product extends Backbone.Collection 

    url: '/api/products' 

    model: Store.Models.Product 

随着视图:

class Store.Views.Origin extends Backbone.View 

    initialize: -> 
    @collection = new Store.Collections.Product() 
    @collection.fetch() 
    @model.bind('change:formatted', @render, this); 
    @render() 

    events: 
    'change [name=origin]': 'setOrigin' 

    el: => 
    @options.parent.$('.origin-input')[0] 

    template: JST["backbone/templates/shapes/product"] 

    render: -> 
    $this = $(this.el) 
    $this.html(@template(model: @model.toJSON(), errors: @model.errors)) 
    console.log(@collection) 
    @collection.each(@appdenDropdown) 
    @delegateEvents() 
    this 

    appdenDropdown: (product) -> 
    console.log("append trigger") 
    #view = new Store.Views.Products(model: product) 
    #$('#history').append(view.render().el) 

与模板:

<div id="history"></div> 

收集工程...

console.log(@collection) 

显示数据!然而,

@collection.each(@appdenDropdown) 

不做任何事情,不会错误或通过任何东西。它只是没有做任何事情。我正试图从集合中提取数据!但它不会...

+0

检查http://stackoverflow.com/questions/8413500/backbone-js-populating-a-collection/ 8415515#8415515或http://stackoverflow.com/questions/11459244/backbone-js-empty-array-attribute/11463190#11463190 – nikoshr 2012-07-19 14:15:34

+2

btw:为什么'$ this = ...'当你有'this。$ el '。我建议阅读backbone.js文档。 – jakee 2012-07-19 14:35:35

+0

并清除nikoshr的答案:collection.fetch是'异步的',并且您可能在提取返回之前在初始化方法中呈现您的视图,因此该集合为空。 console.log是'wtfsynchronous',所以它不管将收集记录为已填充。你必须做的是将渲染方法绑定到集合的重置事件,以确保视图在集合被填充后也被渲染 – jakee 2012-07-19 14:43:41

回答

3

这是因为集合中没有任何东西。

@collection.fetch()在初始化器中是异步方法。在迭代收集项目之前,您必须等到获取完成。

fetch()函数带有一个可选的成功回调函数,当提取完成时触发它。

因此,您可以更新您的初始化程序代码,直到在调用render之前获取集合。这是代码。

initialize: -> 
    @collection = new Store.Collections.Product() 
    @collection.fetch 
    success: => 
     @render() 
+0

在集合填充之前是否可以停止所有操作? – 2012-07-19 15:05:18

+0

@CharlieDavies我更新了我的回答,以反映你的问题 – Paul 2012-07-19 15:13:31

+1

@CharlieDavies这种类型击败了MVC等待那样。你可以采取的另一种方法是让视图监听集合重置以执行渲染。 this.collection.on('reset',this.render,this);所以当你进行你的提取(触发'重置'事件)时,渲染将自动被调用。 – 2012-07-19 19:46:04

0

如其他人所说的问题是fetch是异步的,但解决的办法是简单:jQuery的deferred对象:

initialize: -> 
    @collection = new Store.Collections.Product() 
    @collection.deferred = @collection.fetch() 

    @model.bind('change:formatted', @render, this); 
    @collection.deferred.done -> 
    @render() 

这里发生的事情是,当你调用@collection.deferred.done,你告诉jQuery要等到集合被加载后才执行render就可以了,这就是你想要的。我认为这应该工作。

一对夫妇deferred很好的参考:

+0

更正:我认为@ Paul使用'success'回调的答案实际上是做同样的事情。 – 2012-07-19 23:24:36

+0

谢谢你的帮助,这对我来说现在更有意义!非常感谢! – 2012-07-22 09:26:25