Javascript 动态定义Ember数据模型的属性

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,

我正在处理一个数据模型,该模型具有一组预定义的属性,这些属性将始终存在,并由用户为其定义其他自定义属性

公司有很多角色。使用此系统的每个公司都希望为其所有角色定义自定义属性,以及所有角色在不同公司中具有的固定属性集

这样的想法是,json api中的角色负载会附带所有属性,不管是自定义的还是非自定义的:

{
  "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')
})