backbone.js:自上次服务器保存以来有变化吗
backbone.js: Is there a change since last server-save?
我有一个主干模型。使用model.set(),我可以设置一个本地值,使用model.save()我可以将整个模型保存到服务器。
我怎么知道,自上次服务器保存以来是否发生了更改,这意味着本地版本已损坏。
model.isNew();仅当模型从未保存到服务器时才有效。
编辑:此答案是在Backbone 1.0版本之前编写的。从当前主干版本(1.2.2)起,hasChanged
不再反映"自上次保存以来"的更改。相反,它反映了"自上次设置以来"的变化。
监听更改事件或检查hasChanged
。
如果模型已更改,则可以保存更改。您甚至可以将保存方法关联到在更改事件发生时激发。
如果不想在更改时保存,请为脏模型设置一个属性,并在显式保存时将其清除。
类似于:
change: function(){
this.dirty = true;
}
save: function(){
// do your save
if(success){
this.dirty = false;
}
}
isDirty: function(){
return this.dirty
}
我正在使用CouchDB,Couch有一个_rev属性,每次保存成功后都会更改。我通过在模型初始化函数中放置以下代码解决了"自上次服务器保存以来"的问题:
initialize : function() {
this.on('change',function(){
if(this.hasChanged('_rev')) {
this.isSaved = true;
}else{
this.isSaved = false;
}
},this);
}
备用选项是将所有更新设置为"静默"更新,然后在需要同步时收集更改:
// Updates
myModel.set({foo: 'bar'}, {silent: true}); // Does not fire a 'changed' event
myModel.set({foobar: 'barfoo'}, {silent: true});
// Sync
if (myModel.hasChanged()) {
console.log(myModel.changedAttributes()); // {'foo':'bar', 'foobar':'barfoo'}
_.each(myModel.changedAttributes(), function(value, key) {
console.log(key+' used to be '+myModel.previous(key)+', but now is '+value);
}
myModel.save();
}
除非您通过{silent:true}选项,否则所有建议侦听更改(使用事件)的答案都是正确的。在这种情况下,您需要覆盖默认的set方法来保存已更改的属性,并在调用save方法后重置该列表。
午夜闪电的答案不正确。如果您调用set方法两次,那么changedAttributes将只返回自上次set调用以来发生更改的属性-它在主干文档中:
changedAttributesmodel.changedAttributes([attributes])
只检索自上次设置以来已更改的模型属性的哈希,如果没有,则为false。
在我的情况下,我用这个代码解决了问题:
(function(_, Backbone) {
'use strict';
var _set = Backbone.Model.prototype.set,
_save = Backbone.Model.prototype.save;
_.extend(Backbone.Model.prototype, {
set: function(key, val, options) {
var options = this._getOptions(key, val, options),
toReturn = _set.call(this, key, val, options);
if(!_.isUndefined(options) && options.silent && !!this.changedAttributes()) {
this.silentChanges = _.extend([], this.silentChanges);
[].push.apply(this.silentChanges, _.keys(this.changedAttributes()));
}
return toReturn;
},
save: function(key, val, options) {
var options = this._getOptions(key, val, options),
toReturn = _save.call(this, key, val, options);
if(!_.isUndefined(options) && options.triggerSilents) {
this.triggerSilentChanges();
}
return toReturn;
},
unset: function(key, options) {
if(!_.isUndefined(options) && options.silent) {
this.silentChanges = _.extend([], this.silentChanges, _.keys(this.changedAttributes()));
}
},
triggerSilentChanges: function() {
if(!_.isEmpty(this.silentChanges)) {
var that = this;
_.each(this.silentChanges, function(key) {
that.trigger('change:' + key);
that.silentChanges = _.without(that.silentChanges, key);
});
Backbone.Model.prototype.trigger.call(this, 'change');
}
},
_getOptions: function(key, val, options) {
if(key == null || _.isObject(key)) {
return val;
}
return options;
}
});
})(_, Backbone);
如果我想获得所有更改的属性,我会在模型中使用silentChages属性。如果我想在保存时为所有已设置/未设置的属性触发事件,我会添加"triggerSilents:true"选项。我还可以通过调用triggerSilentChanges方法手动触发所有更改事件。
为了参考,我制作了一个小代码段,它取代了默认的Backbone.sync方法。
被替换的Backbone.sync计算出自上次save()以来哪些Attributes发生了更改,并且它同时适用于模型和集合。
https://github.com/ChiefORZ/backbone.dirty-sync
- html表单,它有文本和表,现在我想在一个简单的文本文件中保存和检索数据,如何实现它
- 如何保存iframe(scrollto)的x和y?有可能吗
- Chrome扩展:是否有一种方法可以运行JavaScript来获取页面上的内部html,并将其保存到扩展中的变量中
- 有没有一个javascript库能够修改和保存图像
- 如何在呈现页面后使用 Java 脚本检测 dom 元素值的值是否有任何变化(例如,任何输入或复选框值更改)
- 为什么 HTML 文本字段的值在有逗号时会发生变化
- 有没有一种方法可以保存单个图像,并防止用户使用dropzone.js放置多个图像
- 在js中有一个cookie保存序列化的svgs
- 用两种方式保存对象,有什么区别
- rails上的两个保存按钮的功能略有不同
- 如何关闭警告此表单上有未保存的更改的消息
- 有没有一种方法可以保存选定的文本,并在刷新页面后再次突出显示它
- 使用未知数量的案例进行切换 - 略有变化的默认情况
- 剑道网格有变化,如何处理只读网格
- backbone.js:自上次服务器保存以来有变化吗
- 如果文本框中有变化,则模糊
- 如何组合两个相似的脚本,并在略有变化的情况下运行它
- 检查窗口大小是否有变化和性能/优化
- 如何知道日期是否有变化的日期picker jQuery
- 当有变化时,自动更新所有用户的HTML dom