【问题标题】:Backbone collection fetch imported incorrectly主干集合提取导入不正确
【发布时间】:2014-10-03 22:04:37
【问题描述】:

我有一个从 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() 数据并将其发送到视图时,这一切都可以正常工作,但是,fetch 被硬编码到渲染函数中,所以 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();

    }

});

编辑:添加新图像以解决问题

【问题讨论】:

  • 你如何检查长度?您的任何代码都没有实际使用它。可能,您在加载项目之前检查长度。
  • 这不是我关心的。我也看到了那些用 console.log() 欺骗你的帖子。问题是过滤器(基于过滤器返回新集合)不返回任何内容。我认为长度部分只是错误的症状。为了清楚起见,如果我过滤已由 .fetch() 填充的集合,它不起作用。如果我过滤由 JSON 的复制粘贴填充的集合(相同的代码),那么它就可以工作。编辑:我会更新一张清晰的图片。
  • fetch 是一个 AJAX 调用,因此在 collection.fetch() 之后您的集合中不会立即有任何内容,您必须等待异步操作完成。
  • 但据我所知有什么?如果不能,请为它清除修复,因为我不明白。

标签: javascript json backbone.js fetch


【解决方案1】:

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

记录对象或数组不像记录原始值,如 stringsnumbers。 当您将对象记录到控制台时,您正在将对该对象的引用记录在内存中。 在第一个日志中,该对象没有模型,但是一旦获取模型,对象就会更新(不是您之前记录的!),现在同一个对象有 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'});
}) 

【讨论】:

  • 我爱你。谢谢,它完全解决了它。我仍然不能完全理解模型存在于集合中的概念,但集合并没有完全更新。现在我只需要弄清楚渲染部分。再次感谢。
  • 渲染部分可以发生在 products.on('sync') 函数内部。同步完成后渲染视图。
【解决方案2】:

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

var that = this;

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

【讨论】:

  • 这看起来很像我以前的(在视图中)——我从这里返回的全部原因是我不清楚在哪里实际进行提取。正如我在主帖中添加的那样,我想最初获取 json 数据(我猜我可以在初始化时这样做),然后将该集合(或任何其他)发送到渲染方法。我来自 C#、Java、C++ 等的世界,所以我的脑袋尖叫着我应该有一个渲染(Collection collectionToBeRendered)。
猜你喜欢
  • 1970-01-01
  • 2013-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多