javascript - 更新模型但保留整个 Backbone 集合

标签 javascript backbone.js backbone.js-collections backbone-model

我的 API 响应:

{
  firstName: '',
  lastName: '',
  notifications: [
    {
      category: '1',
      subcategory: '',
      source: '',
      optInDate: '',
      optOutDate: '',
      active: ''
    },
    {
      category: '2',
      subcategory: '',
      source: '',
      optInDate: '',
      optOutDate: '',
      active: ''
    }
  ]
}

我对应的响应的 Backbone 实现是:

var Notification = Backbone.Model.extend({
  initialize: function (args) {  },
});

var Notifications = Backbone.Collection.extend({
  model: Notification,
  url: '/xyz/abc',

  parse: function (data) {
    return data.notifications;
  },
});

我只想用 active: true 更新“类别 1” 模型(这始终是正确的),但将整个集合保留在我的请求负载中,而不是只是改变了模型。我们怎样才能有骨气做到这一点呢?

我尝试获取该特定模型并执行 model.set({active: true}) 并调用 model.save() 但仅发送该模型到服务器。

我需要将整个响应与更新的模型一起保留回服务器。

编辑:

我能够通过 @Khang's help 实现这一目标在他下面的回答中。但是我忘了提及,我还需要随集合一起发送其他属性,即上述响应中的 firstNamelastName

我正在重写 parse 方法以包含它们,如下所示:

parse: function(data) { 
  this.firstName = data.firstName; 
  this.lastName = data.lastName; 
  return data.notifications; 
} 

当我调用Backbone.sync时,它仍然只发送有效负载中的集合。这是因为我在解析方法中只返回来自数据对象的通知吗?

最佳答案

我想说不要使用 syncKhang suggests并且重写Backbone.sync函数应该极其谨慎,因为它是由每个模型和集合共享的。

虽然它现在适用于您的用例,但从长远来看,它更像是一个补丁。


the API expects the whole DTO to be sent back in the payload to maintain RESTFul

如果 API 真正是 RESTful,它将提供一个端点来单独管理通知。

作为 future 读者的引用,请创建一个端点来单独管理模型。这是创建 REST API 时要采取的方法。我在 another answer 中回顾了这种技术与 Backbone 的优缺点。 .

API is not open to changing their implementation

既然你不能,这意味着API响应代表一个模型,而不是一个集合。Backbone提供基于RESTful API的预定义行为,其中对象应该是模型和数组对象的数量应该是一个集合(异常(exception)是当接收带有页数等集合的元数据时)。因此,主干集合没有 save 功能,不应该全部保存立刻。

就您而言,看起来用户模型可能可以完成这项工作。

请注意,有很多 alternatives to implement a collection within a model 。这是一个简单的例子。

var UserModel = Backbone.Model.extend({
    urlRoot: '/xyz/abc',
    initialize: function(attrs, options) {
        // init a collection within the model
        this.notifications = new Notifications((attrs || {}).notifications);
        // update the collection whenever the model is synced.
        this.listenTo(this, 'sync', this.onSync());
    },

    // Useful abstraction that doesn't interfere with the normal use-case
    saveNotifications: function() {
        return this.save({
            notifications: this.notifications.toJSON()
        }, { patch: true });
    },

    onSync: function() {
        this.notifications.reset(this.get('notifications'));
    }
});

您可以像使用其他模型一样使用该模型

var user = new UserModel({ id: 'user-id-1' });
user.fetch();

当您需要通知时,它们已经在方便的集合中可用。

var notif = user.notifications.findWhere({ category: '1' });
if (notif) {
    notif.set({ active: true });
    user.saveNotifications();
}

用户模型上的 sync 和通知集合上的 reset 等主干事件将正确触发。

在处理大量数据时,这种技术有其缺点,无论如何,一次性保存所有集合应该会暴露出来。 延迟加载分页是在这种情况下提高性能的方法,显然,遵循 REST best practices会有很大帮助。

在我们公司,我们的 API 深受 "Build APIs you won't hate" 的启发。我很高兴我们正在使用这本书。

关于javascript - 更新模型但保留整个 Backbone 集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47841463/

相关文章:

javascript - 使用 Javascript 和 HTML 创建幻灯片放映

javascript - Nodejs - Spotify API 刷新 token

javascript - Flowtype - 如何为类工厂编写声明,例如 Backbone 模型?

backbone.js - 是否可以知道哪一个触发了Collection的add事件: fetch or create call?

inheritance - Backbone : Inherited Models not working in Collection with ID

javascript - 在 Backbone View 中使用函数

javascript - 使用 Javascript XMLHttpRequest 将图像发布到 Picasa

javascript - 如何定位下一张要显示的图像?

ruby-on-rails-3 - Rails 与 Backbone : Who should be responsible for templates and views?

javascript - 如何设置backrid中单元格的高度和宽度