Javascript 动态定义Ember数据模型的属性
我正在处理一个数据模型,该模型具有一组预定义的属性,这些属性将始终存在,并由用户为其定义其他自定义属性 公司有很多角色。使用此系统的每个公司都希望为其所有角色定义自定义属性,以及所有角色在不同公司中具有的固定属性集 这样的想法是,json api中的角色负载会附带所有属性,不管是自定义的还是非自定义的:Javascript 动态定义Ember数据模型的属性,javascript,json,ember.js,ember-data,json-api,Javascript,Json,Ember.js,Ember Data,Json Api,我正在处理一个数据模型,该模型具有一组预定义的属性,这些属性将始终存在,并由用户为其定义其他自定义属性 公司有很多角色。使用此系统的每个公司都希望为其所有角色定义自定义属性,以及所有角色在不同公司中具有的固定属性集 这样的想法是,json api中的角色负载会附带所有属性,不管是自定义的还是非自定义的: { "id": "123", "type": "roles", "attributes": { "name": "CEO", "salary": 100000,
{
"id": "123",
"type": "roles",
"attributes": {
"name": "CEO",
"salary": 100000,
"favoriteColor": "blue"
}
}
在上述角色中,name
和salary
是默认属性,存在于所有角色中,无论公司如何,但favoriteColor
是一个自定义属性,拥有此角色的特定公司将其定义为其所有角色都需要的属性
考虑到我无法在角色模型定义中定义这些自定义属性,我想知道我是否可以使用余烬数据解决类似问题:
// app/models/role.js
export default DS.Model.extend({
name: DS.attr('string'),
salary: DS.attr('number'),
})
更糟糕的是,这些自定义属性不一定是字符串值,但也可以指定其类型。因此,公司可能希望拥有string
类型的favoriteColor
,以及date
类型的birthDate
,我会添加一个属性(您的服务器需要在config
属性中返回附加参数):
及
选项1:通过自定义序列化程序的normalize
功能将序列化处理到属性中,该功能将config
中的值推送到序列化属性中。大概是这样的:
// serializers/role.js
export default <Your Base Serializer>.extend({
normalize(typeClass, hash) {
const result = this._super(typeClass, hash);
result.data.attributes = Object.keys(data.attributes.config).reduce((acc, value) => {
acc[value] = result.data.attributes.config[value];
return acc
}, result.data.attributes);
return result;
},
});
使用可自定义的数据格式化程序,它可能对自动创建余烬数据模型非常有帮助。此外,还可以从您的ember数据模型自动创建正确的JSON:)
// serializers/role.js
export default <Your Base Serializer>.extend({
normalize(typeClass, hash) {
const result = this._super(typeClass, hash);
result.data.attributes = Object.keys(data.attributes.config).reduce((acc, value) => {
acc[value] = result.data.attributes.config[value];
return acc
}, result.data.attributes);
return result;
},
});
// app/models/role.js
export default DS.Model.extend({
name: DS.attr('string'),
salary: DS.attr('number'),
config: DS.attr(), // accepts anything, including json
favoriteColor: Ember.computed.alias('config.favoriteColor')
})