【问题标题】:Backbone.Model save -- returned model's child is array not Backbone.Collection.Backbone.Model 保存——返回模型的子节点是数组而不是 Backbone.Collection。
【发布时间】:2013-02-01 11:05:29
【问题描述】:

我有一个看起来像这样的模型:

var Playlist = Backbone.Model.extend({
    defaults: function() {
        return {
            id: null,
            items: new PlaylistItems()
        };
    }
});

其中 PlaylistItems 是 Backbone.Collection。

创建播放列表对象后,我调用 save。

playlist.save({}, {
    success: function(model, response, options) {
        console.log("model:", model, response, options);
    },
    error: function (error) {
        console.error(error);
    }
});

在这里,我的模型是一个 Backbone.Model 对象。但是,它的子项 items 是 Array 类型,而不是 Backbone.Collection。

这是出乎意料的行为。我错过了什么吗?或者,我是否需要手动将我的数组传递到一个新的 Backbone.Collection 并自己初始化它?

【问题讨论】:

  • Backbone 默认情况下不支持集合的保存/同步,因此可能发生的情况是,在模型进行往返之后,结果 JSON 数组按原样使用。集合旨在成为Models 的集合(用于管理它们自己的持久性)。如果 PlaylistItems 是聚合根的子项,那么您可能不应该从使用 Collection 开始。
  • 我调用的是模型而不是集合上的保存。我不认为在保存期间加载一个模型集合的孩子是不合理的......你是说 Backbone 认为这是不好的做法吗?如果是这样,你知道为什么吗?这似乎是一个常见的 1 到 0+。

标签: javascript backbone.js


【解决方案1】:

这在某种程度上取决于您的服务器期望什么以及它响应什么。 Backbone 不知道属性items 是一个Backbone 集合以及如何处理它。取决于您的服务器,这样的事情可能会起作用。

 var Playlist = Backbone.Model.extend({
    defaults: function() {
        return {
            id: null,
            items: new PlaylistItems()
        };
    },
    toJSON: function(){
        // return the json your server is expecting.
        var json = Backbone.Model.prototype.toJSON.call(this);
        json.items = this.get('items').toJSON();
        return json;
    },
    parse: function(data){
        // data comes from your server response
        // so here you need to call something like:
        this.get('items').reset(data.items);
        // then remove items from data: 
        delete data.items;
        return data;
    }

});

【讨论】:

  • 你怎么把data.items删了再回来?修改 data.items 使其成为 Backbone.Collection 不是更有意义吗?
  • 您从 parse 返回的对象在模型上获得set(),因此如果您创建了一个新的集合并返回它,模型将为items 提供一个新的集合实例。如果您将“重置”事件或任何其他事件连接到先前的 Collection 实例,它将不再起作用。使用新的 json 调用 reset() 会保持相同的实例,因此“重置”事件处理程序仍会被命中。
  • 会说 data.items = new PlaylistItems(data.items);然后返回数据达到相同的结果?还是有什么不同?如果不同,你能解释为什么吗?我想我明白了,但我想确定..
  • 现在,如果您有权更改 REST API,您可以并且也许应该按照 @Matt 的建议为各个播放列表项创建端点。然后,当您添加播放列表项目时,您将使用 playlistItems.create() 并传入新项目的 json。
  • data.items = new PlaylistItems(data.items) 创建一个新实例。如果你在代码中的其他地方有一些事件处理程序,比如playlist.get('items').on('reset', doSomethingOnReset),它会中断,因为它连接到你替换的实例。
猜你喜欢
  • 2013-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多