2014-10-03 35 views
1

我有一个从REST端点获取的集合,它在其中接收JSON。导入的主干集合提取不正确

所以要彻底清除:

var Products = Backbone.Collection.extend({ 
    model: Product, 
    url : 'restendpoint', 

    customFilter: function(f){ 
     var results = this.where(f); 
     return new TestCollection(results); 
    } 

}); 

var products = new Products(); 

products.fetch(); 

如果我登录这一点,那么我的数据。但是,对象的长度(初始值)是0,但它有6个模型。我认为这种差异与什么是错误有关,没有我知道什么是错误的。

现在,如果我试图筛选这样的:

products.customFilter({title: "MyTitle"}); 

返回0,即使我知道有特定标题之一。

现在时髦的部分。如果我参加了整个JSON和复制,如字面上复制/粘贴到这样的代码:

var TestCollection = Backbone.Collection.extend({ 

    customFilter: function(f){ 
     var results = this.where(f); 
     return new TestCollection(results); 
    } 
}); 

var testCollectionInstance = new TestCollection(COPY PASTED HUGE JSON DATA); 
testCollectionInstance.customFilter({title: "MyTitle"}); 

现在返回1个模型,我所期待的。我记录两个集合时的差异可以在下面看到。 .fetch()中有一些奇怪的行为,我不知道?

编辑2:它也可能是有价值的使用.fetch()我没有问题实际上在视图中使用模型。这只是过滤部分很时髦。

编辑3:添加了视图。很可能,我只是没有得到流量。基本上,当我只需要读取()数据并将其发送到视图时,我已经将它全部工作,但是,获取已硬编码到渲染函数中,因此this.fetch({success:send to template});这可能是错误的。

我想要做的是能够过滤集合并将任何集合发送到呈现方法,然后使用该集合呈现模板。

var ProductList = Backbone.View.extend({ 
    el: '#page', 

    render: function(){ 
     var that = this; /* save the reference to this for use in anonymous functions */ 
     var template = _.template($('#product-list-template').html()); 
     that.$el.html(template({ products: products.models })); 
     //before the fetch() call was here and then I rendered the template, however, I needed to get it out so I can update my collection and re-render with a new one (so it's not hard-coded to fetch so to speak) 
    }, 

    events: { 
     'keyup #search' : 'search' 
    }, 

    search : function (ev){ 
     var letters = $("#search").val(); 

    } 

}); 

Difference when logged

编辑:新的图像添加到clearify问题 Model filtering differences

+0

你是如何检查的长度是多少?你的代码没有实际使用它。在加载项目之前,您可能正在检查其长度。 – loganfsmyth 2014-10-03 22:11:59

+0

这不是我所关心的。我看到这些帖子以及console.log()欺骗你。问题是过滤器(它返回基于过滤器的新集合)不会返回任何内容。我认为的长度部分仅仅是什么是错误的症状。为了清除,如果我过滤由.fetch()填充的集合,它不起作用。如果我过滤由JSON的复制粘贴填充的集合(相同的代码),那么它就可以工作。编辑:我会更新一张清晰的图片。 – Dennis 2014-10-03 22:15:13

+1

'fetch'是一个AJAX调用,所以在'collection.fetch()'后面不会有任何东西在你的集合中,你必须等待异步操作完成。 – 2014-10-03 22:21:23

回答

2

这有点棘手,您需要了解控制台的工作方式。

记录对象或数组不像记录原始值,如字符串数字。 当您将一个对象记录到控制台时,您将在内存中记录对该对象的引用。 在第一个日志中,对象没有模型,但是一旦模型被获取,对象就会被更新(而不是你之前记录的!),现在同一个对象有6个模型。它是相同的对象,但控制台打印当前值/属性。

要回答你的问题,IO是异步的。您需要等待从服务器获取对象。这是事件的目的。 fetch触发sync事件。取回完成后,模型会发出sync

所以:

var Products = Backbone.Collection.extend({ 
    model: Product, 
    url : 'restendpoint', 

    customFilter: function(f){ 
     var results = this.where(f); 
     return new TestCollection(results); 
    } 
}); 

var products = new Products(); 

products.fetch(); 

console.log(products.length); // 0 

products.on('sync',function(){ 
    console.log(products.length); // 6 or whatever 
    products.customFilter({title: 'MyTitle'}); 
}) 
+0

我爱你。谢谢,它完全解决了它。我仍然无法完全理解模型存在于集合中的概念,但集合并未完全更新。现在我只需要弄清楚渲染部分。再次感谢。 – Dennis 2014-10-04 18:46:49

+0

渲染部分可能发生在products.on('sync')函数内部。同步完成后呈现视图。 – iggy2012 2014-11-05 18:32:49

0

好像到你的Ajax请求的响应并没有被运行customFilter时尚未收到。您应该能够使用以下内容来确保请求已完成。

var that = this; 

this.fetch({ 
    success: function() { 
     newCollection = that.customFilter({ title: 'foo' }); 
    } 
}); 
+0

这看起来非常像我以前的样子(在视图中) - 我从这回归的全部原因是,我不清楚在哪里实际进行抓取。正如我添加到主帖子,我想最初获取json数据(我可以在初始化我猜),然后将该集合(或任何其他)发送到呈现方法。我来自C#,Java,C++等世界,所以我的头尖叫我应该只有一个渲染(Collection collectionToBeRendered)。 – Dennis 2014-10-04 10:15:38