回答
当前主干不支持将模型的一部分发送到服务器。这将是一个有趣的补充,但。
如果你browse the source你可以看到Backbone.sync
(负责与数据存储通信的骨干部分)是骨干网中最简单的组件之一,并简单地将Ajax支持包装在jQuery或Zepto中。
UPDATE
开始骨干版本0.9.10,局部模型更新通过
model.save(attrs, {patch: true})
骨干原生支持不支持这个开箱即用,但你拥有所有的工具做到这一点。 如果你看Backbone.sync,你会看到它在你的模型上调用JSON来获取实际的数据发送。现在你可能要调整了这一点,但这里是它的要点:
initialize: function(){
this.dirtyAttributes = {}
},
set: function(attrs, options){
Backbone.Model.prototype.set.call(this, attrs, options);
_.extend(this.dirtyAttributes, attrs);
},
toJSON : function(){
json = this.dirtyAttributes;
this.dirtyAttributes = {};
return json;
}
如果你想你需要同样的逻辑适用于未设置,清晰,保存等完整的解决方案,但我猜你得到如何做到这一点。我把脏属性的重置置于toJSON函数中,但它确实应该在成功回调中(当调用保存时)。
谢谢你的回答。我接受了另一个,因为他速度更快:-)。 – ggarber 2011-03-11 16:08:37
@gustavogb好吧,谢谢让StackOverflow变得更糟。 – 2012-07-12 14:03:17
我会更进一步,只标记为实际已更改的脏属性。将属性值设置为原始值(从服务器加载时)应将其标记为干净(不再脏)。这在lib中会有意义吗?我应该提交补丁吗?请注意'{patch:true}'的当前行为不会这样做。 – 2013-04-30 13:01:10
如果您需要发送更新请求到服务器只是一个特定的属性,你可以做同样的事情:对
saveAttributes: (attributes, options={}) ->
data = {}
_(attributes).each (attribute) =>
data[attribute] = @get(attribute)
params =
data: $.param(data)
_.extend(params, options)
Backbone.sync('update', null, params)
更多信息:https://github.com/documentcloud/backbone/pull/573
您可以_.extend Backbone.Model.prototype
后面马上将所有字段标记为“脏”,我必须指定'A'url'属性或函数。错误:必须指定'url'属性或函数 backbone_rails_sync.js:15' – lulalala 2012-08-27 08:21:46
我尝试了几个这里提出的技术,但最终决定直接修改Backbone.Model和Backbone.sync。我想提供的是提供这种功能的微创方法,它不需要指导我的团队中的开发人员使用重要的主干方法;太容易出错。我的解决方案只涉及将选项传递给模型的“保存”方法。例如:
//Note that this could be from your view or anywhere you're invoking model.save
saveToModel : function() {
this.model.save({
field1 : field1Value,
field2 : field2Value,
field3 : field3Value
}, {partialUpdate : true}
}
现在,启用此功能,我做了一些非常小的修改Backbone.Model.save和Backbone.sync。这里的变化Backbone.Model.save:
//If a partialUpdate is required, create a member on the options
//hash called updateAttrs and set it to attrs
if (options.partialUpdate != "undefined" && options.partialUpdate) {
options.updateAttrs = attrs;
}
//--->>>Put the block above right above the return line
return (this.sync || Backbone.sync).call(this, method, this, options);
这里会发生什么情况是,如果partialUpdate作为一个选项传递,然后一个新的成员被称为updateAttrs上的选项哈希创建。选项散列自动传递给Backbone.sync。
对于Backbone.sync,我改变了以下条件:
// Ensure that we have the appropriate request data.
if (!params.data && model && (method == 'create' || method == 'update')) {
params.contentType = 'application/json';
params.data = JSON.stringify(model.toJSON());
}
到...
// Ensure that we have the appropriate request data.
if (!params.data && model && (method == 'create' || method == 'update')) {
params.contentType = 'application/json';
//If doing a partial model update, then grab the updateAttrs member
//from options. Will not interfere with line directly below as params.data
//will have been set.
params.data = (options.partialUpdate != "undefined" && options.partialUpdate)
? params.data = JSON.stringify(options.updateAttrs)
: params.data = JSON.stringify(model.toJSON());
}
添加额外的条件检查,看是否partialUpdate设置,那么如果是,设置params.data到options.updateAttrs。这将被传递给jQuery Ajax方法。
UPDATE:开始骨干版本0.9.10,部分更新是通过本地
model.save(attrs, {patch: true})
支持直到0.9.9 的一种方法,而不直接编辑Backbone.js的库文件。只需将以下代码添加到应用程序js文件中,并在backbone.js加载后加载它。
//override the Backbone.sync to send only the changed fields for update (PUT) request
var Original_BackboneSync = Backbone.sync;
Backbone.sync = function(method, model, options) {
/* just handle the data picking logic for update method */
if (!options.data && model && method == 'update') {
options.contentType = 'application/json';
options.data = JSON.stringify(model.changedAttributes() || {});
}
//invoke the original backbone sync method
return Original_BackboneSync.apply(this, arguments);
};
//Tested in Backbone.js 0.9.1
这是一项很酷的技术。 – 2012-05-21 18:41:41
这个版本似乎比原生版更好! – exussum 2013-06-26 12:35:45
'changedAttributes'只包含最后一次调用到'.set()'的变化,所以如果你做了'm.set('p1',1); m.set('p2',2); m.save();'它只会发送'{p2:2}'不是所有更新的字段。 – CodingWithSpike 2016-03-15 20:50:12
而是覆盖Backbone.sync
的,你可以做它的Model.sync
方法内。由于您无法在那里访问model.changedAttributes()
,请务必在此方法内始终返回false。
sync: (method, model, options) ->
if method is "update"
options.contentType = 'application/json'
changedData = {}
for attr in _.keys(options.changes)
changedData[attr] = model.get(attr)
options.data = JSON.stringify changedData
Backbone.sync method, model, options
使用Jayyy V的(非常好)的答案,我重写它一点点,使同步功能采取白名单,所以你可以给它得到保存键数组。
var Original_BackboneSync = Backbone.sync;
Backbone.sync = function(method, model, options) {
/* check if a whitelist was in options */
if (options.whitelist) {
options.contentType = 'application/json';
/* use underscore method for picking only whitelisted attributes to save */
options.data = JSON.stringify(_.pick(model.attributes, options.whitelist));
}
//invoke the original backbone sync method
return Original_BackboneSync.apply(this, arguments);
};
这里的大多数答案是直接或间接修改sync
函数。这是我的小技巧来解决这个问题:
当你打电话给model.save
时,你实际上可以传入第二个参数,当Backbone尝试调用同步时将传递给$.ajax
。我不喜欢这样的部分更新,更明确地规定哪些字段提交:
/**
* On user clicking on "mark important"
*/
onMarkImportantBtnClick: function() {
var marked = this.model.get('UserFeed.marked_important'),
data = {
UserFeed: {
marked_important: !marked
}
};
this.model.save(data, {data: JSON.stringify(data), contentType: 'application/json'});
}
这个动作更新我的模型正确的属性,加上发送到在JSON.stringify
提到的服务器只能将资料。 contentType
这里需要,更好地
这是因为Backbone.sync
has these lines,并且我们通过传递data
属性否定它:
if (!options.data && model && (method == 'create' || method == 'update')) {
params.contentType = 'application/json';
params.data = JSON.stringify(model.toJSON());
}
信用此页:https://plus.google.com/103858073822961240171/posts/1gTcu6avmWQ
注:该模型继承自powmedia的DeepModel以支持嵌套模型属性
编辑自骨干0.9.9,patch
选项已被添加
所以这一招只适用于以前的版本。
要只提交脏数据传回服务器,供应{patch: true}
在save
,这样
this.model.save(modifiedData, {patch: true});
感谢@Lincoln B中指点一下。
最好的答案在这里,谢谢你的来源。 Backbone 0.9.9增加了{path:true}来保存,但是如果你现在不能升级,这是理想的事情。我个人定义了一个单独的补丁,如补丁:(attributes,options = {}) - > this.save(attributes,{data:JSON.stringify(attributes)}) – 2013-01-17 23:41:38
是的。此解决方案仅适用于较旧的Backbone版本。新的“补丁”很酷! – 2013-01-18 01:41:58
在@ Julien的帖子上创建: 您可以将其添加到您的模型中,它只会发送您传入的属性,而不是整个模型。您仍然可以使用save作为默认行为,并且您可以在发送那些作为参数传入的属性时使用partialSave。我已经测试过了,它对我有用。
partialSave: function(attr, options) { //use this method instead of save()
this.dirtyAttributes = attr;
this.save(attr, options);
},
toJSON: function() { //overrides Backbone.Model.prototype.toJSON
if (this.dirtyAttributes) {
var attr = this.dirtyAttributes;
this.dirtyAttributes = null;
return attr;
}
return Backbone.Model.prototype.toJSON.apply(this, arguments);
},
事实上,有实现这一
的更简单的方法,如果你看一下Backbone.js的线1145,你会看到
// Ensure that we have the appropriate request data.
if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
params.contentType = 'application/json';
params.data = JSON.stringify(options.attrs || model.toJSON(options));
}
这意味着你可能会覆盖数据部分xhr通过将数据放入您的选项
由于骨干保存需要model.save([attributes], [options])
但请记住,属性,如ID可能是必要的适当的储蓄
例
model.save({}, { data: JSON.stringify(data) }) ;
所以,你应该做这样的事情
var data = { id : model.id , otherAttributes : 'value' } ;
或
var data = model.toJSON() ;
remove data.tempData ;
最后
model.save({}, { data : JSON.stringify(data) });
该做的伎俩相当不错的我,还可能与XHR如获取,保存,删除,任何骨干网使用...
与保存,同步或看的toJSON这样的错误
梅辛我创建了扩展模型。用法
var CModel = Backbone.Model.extend({
save: function(attributes, options) {
if(_.isUndefined(options)) {
options = {};
}
var isNeedAttrsRefresh = false,
basicAttributes = null;
if(!_.isUndefined(options.fields)) {
basicAttributes = _.clone(this.attributes);
var newAttributes = {};
_.each(this.attributes, function(value, name) {
if(options.fields.indexOf(name) > -1) {
newAttributes[name] = value;
}
});
this.attributes = newAttributes;
isNeedAttrsRefresh = true;
}
this.isSaving = true;
var result = Backbone.Model.prototype.save.apply(this, arguments);
this.isSaving = false;
if(isNeedAttrsRefresh) {
this.attributes = basicAttributes;
}
return result;
}
});
例子:
var CommentModel = CModel.extend({ ... }
,并允许领域节省:
comment.save(null, { fields: ['message', 'entry_id', 'module_id', 'parent_id'] });
- 1. backbone.js:如何使用.set()部分更新模型json对象?
- 2. 更新模型的一部分
- 3. 更新部分映射模型
- 4. 在Rails中部分更新模型3
- 5. 只更新模型的一部分
- 6. backbone.js:更新模型,重新排序和重新渲染模型集合
- 7. backbone.js在视图更改时更新模型的正确方法
- 8. 模型Backbone.js的
- 9. Backbone.js模型
- 10. Backbone.js - 与另一个视图共享模型的一部分
- 11. 在backbone.js中更改视图的模型
- 12. Backbone.js模型缓存
- 13. 运输backbone.js模型?
- 14. backbone.js复杂模型
- 15. 如何更新集合中的所有模型 - Backbone.js
- 16. 在Backbone.js中处理模型更新服务器响应
- 17. 在不擦除旧模型的情况下更新Backbone.js集合
- 18. 保存Backbone.js模型并更新整个集合
- 19. 更新模型W/Backbone.js的+ Rails的工作不
- 20. Backbone.js从服务器就地更新模型
- 21. backbone.js批量更新
- 22. 更新部分
- 23. 的EntityFramework更新局部模型
- 24. JQuery Sortable + Rails - 更新外部模型
- 25. 部分模型验证在创建/更新方案
- 26. 如何在MVC5的部分视图中更新视图模型?
- 27. 只更新模型的一部分,验证问题?
- 28. Knockout.js映射。如何只更新视图模型的一部分?
- 29. MVC - 部分在视图中更新模型
- 30. Backbone.js的更改模型的URL参数,并获取不更新数据获取
这是现在支持为0.9.9版本,如果你只希望改变的属性发送到服务器,调用model.save(attrs,{patch:true})。只需传入的属性即可获得到服务器的HTTP PATCH请求。 http://backbonejs.org/#Model-save – Ben 2013-01-06 19:18:50