我有一个用户模型(Backbone.js),我想更新其设置属性,然后将其保存到服务器。设置是JSON格式,我设置的方式是设置是字符串版本,settingsJSON是对象版本。我将函数绑定到每个更改事件,以便在更改时更新另一个。
我遇到的问题是,在更改的处理程序运行完毕之前,save方法正在运行。有什么方法可以确保该模型的所有事件处理程序都是完整的或类似的东西吗?
我是怎么称呼的:
currentUser.get('settingsJSON').apps = appsEnabled;
currentUser.save();
我的事件处理程序:
Initialize: function() {
var that = this;
this.on("change:settingsJSON", function(model){
model.set({settings: JSON.stringify(model.get('settingsJSON'))});
});
this.on("change:settings", function(model){
model.set({settingsJSON: JSON.parse(model.get('settings'))});
});
}
@fencliff:
更改事件在我运行并且正常工作时触发,我让它将新设置字符串打印到控制台。
你确定它们是同步调用的吗?我在console.log('changed')
的末尾添加了.on(change)
,并在console.log('saved')
之后直接放置currentUser.save()
,并且每次控制台都会读取:
saved
changed
现在我刚刚创建它,以便在保存之前直接将JSON保存到设置中,并且工作正常。
答案 0 :(得分:2)
Backbone事件同步执行。这意味着除非您(或某些库)覆盖了事件处理的某些部分,否则更改处理程序将在您执行下一行代码时立即处理。
在您的代码示例中,还有另一个问题。当你打电话
user.get('settingsJSON').apps = appsEnabled;
change
事件将不触发,因为settingsJSON
的值尚未更改,仅修改了对象的内容。 model.attributes.settingsJSON
仍然是与以前相同的对象。
仅当您在属性上调用set
并且新值为不同的对象时,才会触发事件。例如:
user.set('settingsJSON', _.extend({}, user.get('settingsJSON'), {apps:appsEnabled});
看起来另一个问题是你的事件处理程序如果被触发,会导致change
事件被首次设置的属性触发两次:
this.on("change:settingsJSON", function(model){
//-> changes settings, and set triggers change
model.set({settings: JSON.stringify(model.get('settingsJSON'))});
});
this.on("change:settings", function(model){
//-> changes settingsJSON, and set triggers change
model.set({settingsJSON: JSON.parse(model.get('settings'))});
});
要解决该问题,请使用set
致电{silent:true}
或直接修改model.attributes
哈希。
已编辑并修改了@muistooshort。
再次编辑并进行进一步更正