Ember.js 更改余烬模型';保存到服务器之前的s值
我有一个余烬模型,有一个我想显示和使用的字段,但是在我从服务器保存或检索它之前,我想将它乘以/除以1000 这意味着UI应始终使用较小的值,但将较大的值保存到服务器。同样,它应该从服务器检索一个更大的值,但在允许控制器、路由等使用该值之前将其缩小Ember.js 更改余烬模型';保存到服务器之前的s值,ember.js,ember-data,Ember.js,Ember Data,我有一个余烬模型,有一个我想显示和使用的字段,但是在我从服务器保存或检索它之前,我想将它乘以/除以1000 这意味着UI应始终使用较小的值,但将较大的值保存到服务器。同样,它应该从服务器检索一个更大的值,但在允许控制器、路由等使用该值之前将其缩小 // models/my_model.js import DS from 'ember-data'; export default DS.Model.extend({ name: DS.attr('string'), value: D
// models/my_model.js
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string'),
value: DS.attr('number')
});
基本上,我希望我的应用程序将这些字段显示为:
/* my webpage */
Please enter name: "foo"
Please enter value: 5
但当我发送请求时,它应将其发送为:
{
"my_model": {
"name": "foo",
"value": 5000
}
}
它还应该以这种格式接收它们,但随后通过除以1000反序列化该值
请注意乘/除1000就是一个例子-我可能需要追加、前置、加、减等
我试着用一种不那么优雅的方式:
// Controller.js
actions: {
save: function() {
this.set('model.value', this.get('model.value') * 1000);
this.get('model').save().then(
/* stuff */
);
this.set('model.value', this.get('model.value') / 1000);
}
}
但我对此并不满意,这会导致代码重复,难以维护,并且容易出错
我有一个RESTSerializer
,但我不知道如何使用它来操作字段,在中找不到任何内容。也许我需要使用不同的序列化程序?我的车到目前为止基本上是空的
// serializers/my_model.js
import DS from 'ember-data';
export default DS.RESTSerializer.extend({
primaryKey: 'name',
});
我用自定义的
序列化
和规范化
(反序列化)方法解决了这个问题:
这对我来说非常有效,而且非常灵活。我建议在该用例中使用。与重写序列化程序的normalize
和serialize
方法相比,它更具可重用性,更好地分离关注点。余烬数据转换可以看作是一个特定于属性的(反)序列化程序。有一些内置转换:字符串
、数字
、布尔值
和日期
。您已经在使用其中的一些
您应该从默认blueprint开始编写自定义序列化程序:ember生成转换货币
。这将生成一个文件app/transforms/currency.js
和相关的单元测试。转换扩展了DS.transform
类,必须实现序列化
和反序列化
方法。它们获取(反)序列化的值作为参数,并应返回相反的值
重构您的示例,作为对转换的回答,如下所示:
//app/transforms/currency.js
从“余烬数据”导入DS;
导出默认的DS.Transform.extend({
反序列化(序列化){
返回序列化/1000;
},
序列化(反序列化){
返回反序列化*1000;
}
});
它可以这样使用:
//models/my_model.js
从“余烬数据”导入DS;
导出默认DS.Model.extend({
名称:DS.attr('string'),
值:DS.attr('货币')
});
最大的好处是,它可以应用于任意多个模型中的任意多个属性。它还可以在与其他序列化问题分离的情况下进行单元测试,并且可以作为一个Ember插件在应用程序之间轻松共享。哇,这看起来非常干净,非常直观。我很想尝试一下!谢谢
// serializers/my_model.js
import DS from 'ember-data';
export default DS.RESTSerializer.extend({
normalizeResponse(store, primaryModelClass, payload) {
payload.my_model.value /= 1000;
return this._super(...arguments);
},
serialize() {
let json = this._super(...arguments);
json.value *= 1000;
return json;
}
});