【问题标题】:Undefined model prototype in Backbone Collection and Marionette CompositeViewBackbone Collection 和 Marionette CompositeView 中未定义的模型原型
【发布时间】:2013-12-20 18:04:16
【问题描述】:

尝试从值列表填充集合时,我收到关于集合的modelprototype 未定义的错误。查看this question about a similar problem,我尽我所能检查了模型实际上是在集合被实例化之前创建的。

在从服务器获取数据并尝试reset 包含应填充数据的值列表的集合之后,在包含集合的 Marionette CompositeView 的事件处理程序之一中引发错误进入它。

注意:使用 Backbone 0.9.10

模型

MyItemModel = Backbone.Model.extend({});

收藏

MyCollection = Backbone.Collection.extend({
    model: MyItemModel
});

CompositeView的相关代码

MyCompositeView = Backbone.Marionette.CompositeView.extend({

    initialize: function(options) {
        _.bindAll(this);
        this.model = new MyCompositeViewModel();
        this.collection = new MyCollection();
    },

    //This event handler gets properly fired and run.
    on_event: function() {
        var that = this;

        // The data comes through fine with this `fetch`
        this.model.fetch({success: function() {
            var collection_results= that.model.get("collection_results");

            // The error fires in this line
            that.collection.reset(collection_results);
            that.render();
        });
    }
})

错误

错误发生在 Backbone 中的 add 函数中,当为模型对象执行 get 时,检查它是否是重复的。失败的代码在这里:

// Get a model from the set by id.
get: function(obj) {
    if (obj == null) return void 0;

    // The error originates from this line
    this._idAttr || (this._idAttr = this.model.prototype.idAttribute);
    return this._byId[obj.id || obj.cid || obj[this._idAttr] || obj];
},

this._idAttr || (this._idAttr = this.model.prototype.idAttribute);

这里,this.model.prototype.idAttribute 失败,因为模型的 prototype 未定义。

为什么会发生这种情况,如何解决?

非常感谢!

【问题讨论】:

  • 您能否在引发错误的行周围包含完整的代码以获得一些上下文?
  • 出错的行是什么文件名和行号?
  • 添加了代码上下​​文。 @einnocent,backbone.js 中的行是 710。
  • 没有您在 Backbone 0.9.2 中提到的代码。 github.com/jashkenas/backbone/blob/0.9.2/backbone.js你确定吗? (只需搜索带有“_idAttr”的页面)
  • @BillyChan:没错!实际上使用0.9.10。感谢您的提醒!

标签: javascript backbone.js prototype undefined marionette


【解决方案1】:

原因是,在 Babkbone 0.9.10 中,如果您在没有选项的情况下调用 collection.reset(models),模型将被传递给 collection.add(),这严格需要真实模型作为参数。

但是,实际上,您传递的参数并不是真正的模型。它们只是一个哈希属性数组。

两个修复选项:

选项 1:使用解析选项调用重置

that.collection.reset(collection_results, {parse: true});

然后reset 将解析散列数组并将其设置为模型。

选项 2:升级到最新版本 Backbone 1.1.0。

这里reset() 不再将责任转嫁给add(),而是巧妙地使用set()。推荐使用此选项。而且这里不需要选项。

that.collection.reset(collection_results)

还有一点

我建议你不要在 CompositeView 中定义model 吗? CompositeView 用于集合,而不是模型。当然我理解这里的模型只是为了保存和获取一些数据,但是代码被另一个开发者阅读以及你自己维护会很混乱。

要获取引导数据,您可以在第一次请求时加载数据并使用常规方式将其放入集合中。 http://backbonejs.org/#FAQ-bootstrap

【讨论】:

  • 谢谢,比利。我会检查并投票。关于在 CompositeView 中不使用模型的建议,如果视图用于具有集合以及与之关联的一些元数据的模型,这不是一个好的模式吗?在这种情况下你会建议什么?再次感谢!
  • @JuanCarlosCoto,我理解你的担忧。也许我太固执了:) 如果真的需要,我自己更愿意使用另一个名字,比如meta 而不是model。我也希望让集合来保存元而不是视图,因为视图不是用于数据,而是用于 DOM 事件。对于其他事情,它应该是愚蠢的。
  • 从头开始。该错误是我在关联文件中所做的一些更改的产物;这实际上解决了这个问题。再次感谢!
猜你喜欢
  • 2013-10-08
  • 1970-01-01
  • 1970-01-01
  • 2013-10-09
  • 1970-01-01
  • 1970-01-01
  • 2017-11-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多