在EmberData中,调用model.save()会使模型通过适当的适配器持久化。如果适配器返回一些数据(例如来自API的JSON),则会使用该数据更新模型。

我偶然发现了一个不正确的序列。

在用于结帐过程的凭证系统中,在voucherCode模型上输入order。当按下“应用”按钮时,订单将通过order.save()保存,凭证即被提交到服务器。

如果凭单代码有效,则在voucherValue字段中填充数字。如果凭单代码无效,则按照http://emberjs.com/api/data/classes/DS.Errors.html返回带有标准422对象的errors错误

现在,这里发生了问题。如果输入的代码返回voucherValue300,则 Controller 属性将计算折扣。

discount: function () {
  var discount = this.get('model.voucherValue');
  // some calculation
  return discount;
}.property('model.voucherValue')

如果由于某种原因,用户随后输入了无效的代码,我们将返回如上所述的错误。服务器删除折扣并将voucherValue设置为0
由于错误响应在catchsave中不包含更新的数据,因此我们手动对其进行更新。
order.save().then(function () {

}).catch(function (error) {

  order.set('voucherValue', 0);
});
discount computed property在设置voucherValue时按预期更新。但是,检查订单模型显示order._data.voucherValue仍然是第一个有效凭证代码中的原始300值-因为EmberData不知道此值会在服务器上保留。

如果然后输入有效的凭证代码,该代码返回voucherValue300(与原来相同),则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

08-19 08:57