2013-01-06 50 views
0

我有用户模型(Backbone.js),我想更新其设置属性,然后将其保存到服务器。设置为JSON格式,我设置的方式是设置是字符串版本,settingsJSON是对象版本。我将函数绑定到每个函数的更改事件,以便在更改时更新另一个函数。在保存模型之前等待更改处理程序完成

我遇到的问题是保存方法在更改的处理程序运行完成之前正在运行。有什么办法可以确保该模型的所有事件处理程序都是完整的或类似的东西?

如何我打电话吧:

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 

现在我刚才提出,以便我stringily的JSON和我之前它直接保存到设置保存并且工作正常。

+0

我*相对*确保事件同步解雇,也是'model.get(“settingsJSON”)。应用= TRUE;将**不* *触发任何事件。但我已经在这个线程中出错了两次,所以我知道什么。这里有一个演示:http://jsfiddle.net/T7jKg/。你可以分叉它,并显示你的代码中发生了什么? – jevakallio

+0

@fencliff我认为必须发生的事情是,这个变化正在被别的东西激发,可能是.save()。不完全确定。我稍后可能会重新讨论这个问题,试图让它工作得如何我想要的,但现在我的修复会起作用 –

回答

2

骨干事件是同步执行的。这意味着,除非您(或某个库)已经重写了事件处理的某些部分,否则只要执行下一行代码,处理程序就会进行处理。

在你的代码示例中还有另一个问题。当你调用

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。

编辑进一步修正再次

+0

你确定这两个'set'调用会触发''change''事件吗? –

+0

@ muistooshort,我不明白他们为什么不这样做,但后来我又醉了,在我的手机上无法测试。他们为什么不呢? – jevakallio

+0

它们不会因为'set'实质上使用'=='来跳过没有改变的设置属性,添加一个新的属性到一个对象将不会改变它的参考值。你需要手动设置一些更像'_.extend({},user.get('settingsJSON'),{apps:appsEnabled})''的东西来强制生成一个新对象,以便你能够过去简单的平等过滤器。 –

相关问题