我的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;
},
});
我想只更新“category 1”模型(这始终是真的),而是active: true
,但是将整个集合保存在我的请求有效负载中,而不仅仅是更改后的模型。我们如何通过骨干实现这一目标?
我已尝试获取该特定模型并执行model.set({active: true})
并调用model.save()
但仅将该模型发送到服务器。
我需要将整个响应与更新的模型一起保存回服务器。
修改
我在下面的回答中用@Khang's help实现了这一点。但是我忘了提到我需要发送其他属性以及集合,即上述响应中的firstName
,lastName
。
我正在覆盖parse
方法以包含它们,如下所示:
parse: function(data) {
this.firstName = data.firstName;
this.lastName = data.lastName;
return data.notifications;
}
当我呼叫Backbone.sync
时,它仍然只在有效负载中发送集合。那是因为我只是在parse方法中返回数据对象的通知吗?
答案 0 :(得分:3)
我要说不要像Khang suggests那样使用sync
而应该非常谨慎地覆盖Backbone.sync
功能,因为它是每个模型和集合共享。
虽然它现在适用于您的用例,但从长远来看,它更像是一个补丁。
API期望将整个DTO发送回有效负载以维护RESTFul
如果API真的是RESTful,它将提供一个端点来单独管理通知。
作为对未来读者的参考,建立一个端点来单独管理模型。这是创建REST API时的方法。我在another answer中考虑了Backbone的这种技巧的优缺点。
API无法更改其实施
因为你不能,这意味着 API响应代表模型,而不是集合。 Backbone提供基于RESTful API的预定义行为,其中对象应该是模型,数组对象应该是一个集合(例外情况是接收带有像页数等集合的元数据时)。由于这个原因,Backbone Collection没有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"的启发,我很高兴我们正在使用这本书。
答案 1 :(得分:0)
我不确定你要做什么,这对我来说似乎不对。如果只有一个模型发生变化,为什么需要将整个集合发送到服务器? Aren已经在服务器上的未更改的模型?我认为你应该重新考虑这种方法。
无论如何,如果你真的需要它,这将实现你想要的:
Backbone.sync("update", Notifications);
更多文档here
<强>更新强>:
如果每次收集sync
时都有许多额外数据要发送,则可以覆盖sync
方法以使集合具有自定义同步行为。否则,您可以在需要时使用options.attrs
获取自定义数据:
Backbone.sync("update", Notifications, {
attrs: {
data: Notifications.toJSON(),
firstName: 'foo',
lastName: 'bar',
}
});
要了解其原因,我建议您阅读Backbone源代码Backbone.sync