在EmberData中,调用model.save()
会使模型通过适当的适配器持久化。如果适配器返回一些数据(例如来自API的JSON),则会使用该数据更新模型。
我偶然发现了一个不正确的序列。
在用于结帐过程的凭证系统中,在voucherCode
模型上输入order
。当按下“应用”按钮时,订单将通过order.save()
保存,凭证即被提交到服务器。
如果凭单代码有效,则在voucherValue
字段中填充数字。如果凭单代码无效,则按照http://emberjs.com/api/data/classes/DS.Errors.html返回带有标准422
对象的errors
错误
现在,这里发生了问题。如果输入的代码返回voucherValue
的300
,则 Controller 属性将计算折扣。
discount: function () {
var discount = this.get('model.voucherValue');
// some calculation
return discount;
}.property('model.voucherValue')
如果由于某种原因,用户随后输入了无效的代码,我们将返回如上所述的错误。服务器删除折扣并将
voucherValue
设置为0
由于错误响应在
catch
的save
中不包含更新的数据,因此我们手动对其进行更新。order.save().then(function () {
}).catch(function (error) {
order.set('voucherValue', 0);
});
discount
computed property
在设置voucherValue
时按预期更新。但是,检查订单模型显示order._data.voucherValue
仍然是第一个有效凭证代码中的原始300
值-因为EmberData不知道此值会在服务器上保留。如果然后输入有效的凭证代码,该代码返回
voucherValue
的300
(与原来相同),则discount
计算的属性不会重新计算。似乎Ember正在根据
order._data
检查返回的数据值,并且由于没有差异,因此不会触发任何属性重新计算。我尝试了不同的解决方法,但是无法找到可靠的方法。
令人沮丧的是,似乎没有可靠的方法来访问返回的数据并根据返回的数据手动设置
voucherValue
。即使返回的数据设置了voucherValue
的值,也是如此:order.save().then(function (savedOrder) {
savedOrder.get('voucherValue') === 0; //true
}).catch(function (error) {
order.set('voucherValue', 0);
});
但是,如果在无效凭单后输入了不同的凭单,并且
voucherValue
不同(例如450
),则一切正常。这是EmberData中的错误吗?有一个已知的解决方法。我乐于接受建议,并愿意尝试任何事情,然后再尝试重新设计整个系统的实现方式。
最佳答案
您的这段代码似乎是一个问题:
order.save().then(function (savedOrder) {
savedOrder.get('voucherValue') === 0; //true
}).catch(function (error) {
order.set('voucherValue', 0);
});
catch
函数是promise捕获的代理。但是,promise通常希望将第二个参数传递给then
函数,如下所示:order.save().then(function (savedOrder) {
savedOrder.get('voucherValue') === 0; //true
}, function (error) {
order.set('voucherValue', 0);
});
此第二个函数表示
reject
使用的resolve/reject
对的Promise
路径。另请:http://emberjs.com/api/data/classes/DS.Model.html#method_save