Backbone集合获取导入不正确

时间:2014-10-03 22:04:38

标签: javascript json backbone.js fetch

我有一个从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:添加了视图。很可能我还没有获得流量。基本上,当我只需要获取()数据并将其发送到视图时,我已经完成了所有工作,但是,fetch被硬编码到render函数中,所以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

编辑:添加新图像以清除问题 Model filtering differences

2 个答案:

答案 0 :(得分: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'});
}) 

答案 1 :(得分:0)

似乎在您运行customFilter时尚未收到对您的ajax请求的回复。您应该能够使用以下内容来确保请求已完成。

var that = this;

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