【问题标题】:Save Backbone.js Model and update entire Collection保存 Backbone.js 模型并更新整个 Collection
【发布时间】:2012-04-17 10:51:55
【问题描述】:

我希望能够在主干模型上调用 save() 并让后端返回此模型的整个集合,而不仅仅是模型的更改属性。然后我希望骨干更新整个返回的集合。用例如下:

一个用户有多个地址,可以从这个集合中选择一个送货地址。如果她从集合中选择不同的送货地址,则应将之前的送货地址更新为“只是另一个普通地址”的状态。为此,必须更新整个集合,而不仅仅是更改的模型。

这在bone.js 中是否可能?

提前非常感谢!

【问题讨论】:

    标签: backbone.js


    【解决方案1】:

    是的,这是可能的。您需要覆盖模型上的 sync 函数

    MyModel = Backbone.Model.extend({
      sync: function(method, model) {
        if (method === 'create') {
          //perform save logic and update the model's collection
        } else if (method === 'update') {
          //perform save logic and update the model's collection
        } else if (method === 'read') {
          ...
        } else if (method === 'destroy') {
          ...
        }
      }
    });
    

    查看 Backbone.sync 函数了解更多信息。

    【讨论】:

    • 我想覆盖同步对这个用例没有太大帮助,因为它不关心从服务器返回的响应(这是成功回调方法的任务)
    【解决方案2】:

    您的用例实际需要的是更新两个模型,而不是更新整个集合。 (除了获取之外,集合不与 Backbone 中的服务器交互。)假设您有地址 A、B 和 C,其中 A 作为当前送货地址,C 作为新送货地址,您的代码可以简单地:

    1. 将 C 更新为新的收货地址。
    2. 将 A 更新为“只是另一个地址”。

    如果您的问题是您不知道哪个地址是当前地址(即地址 A),那么您可以在您的收藏中搜索它(即“给我当前收货地址”),更新C,然后更新返回地址(地址A)。

    如果您绝对需要更新整个集合(您不需要),请循环浏览collection.models 并单独更新每个集合。 Backbone 中根本没有集合被 RESTfully 操作的概念。

    编辑:我可能误读了您的问题。如果您的意思是更新客户端上的集合(即,您不打算更新服务器上的集合),那么代码仍然相似,您只需更新旧模型和新模型即可。

    【讨论】:

    • 是的,我实际上是要更新客户端上的集合,这也是上述方法的问题,因为如果我只是将 C 和 A 更新为客户端上的新状态,它们的状态就会失效如果无法成功保存在服务器上,则与服务器同步。
    【解决方案3】:

    我认为这里不需要覆盖同步或打破对保存返回的期望。

    我想在模型上覆盖save 会更简单,类似于:

    save: function (key, value, options) {
        var p = Model.prototype.save.call(this, key, value, options),
            self=this;
        if (this.collection) {
            p.done(function () { self.collection.fetch(); });
        }
        return p;
    }
    

    它将使用普通的save获取它的promise进行保存,然后如果保存成功并且模型是集合的一部分,它将从服务器获取集合。

    另一种方法是绑定到模型的 change 事件,检查它是否属于集合并获取,但这也会发生在 set 上。

    【讨论】:

    • 我没有尝试过,但我想这实际上可以解决额外请求周期带来的一点不便。
    • @Hendrik 你在哪里看到了额外的循环?
    • 好吧,如果我在这里没有遗漏任何东西,模型会首先保存,如果成功,那么客户端会获取集合。相反,如果服务器只是在模型成功存储后直接返回集合,则整个操作需要少一个请求。我错了吗?
    • 不,你不是!我错过了你真正想要的东西。
    【解决方案4】:

    绑定到集合的模型包含其集合父级作为属性。此外,由于您返回了一个模型列表,我们可以假设它始终在一个列表中。

    mymodel = Backbone.Model.extend({
       parse: function (data) {
         if(this.collection && typeof(data) === 'array') {
            this.collection.reset(data);
         }
         return data;
       }
    });
    

    【讨论】:

    • "typeof(data) === 'array'" 应该是 "_.isArray(data)",顺便说一句。
    猜你喜欢
    • 1970-01-01
    • 2012-03-27
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-17
    • 2012-04-06
    相关资源
    最近更新 更多