ExtJS 模型与 jsonapi 规范的关联
Posted
技术标签:
【中文标题】ExtJS 模型与 jsonapi 规范的关联【英文标题】:ExtJS model associations with jsonapi specification 【发布时间】:2021-04-01 01:04:51 【问题描述】:我们正在创建一个采用 JSON:API 规范 (https://jsonapi.org/) 的 API (v2) 新版本。我无法将 ExtJS 模型关联 (belongs_to) 移植到新模式。
ExtJS 文档只展示了如何在同一个根节点 (https://docs.sencha.com/extjs/4.2.2/#!/api/Ext.data.association.Association) 中使用嵌套关系。
v1 数据(样本):
"data": [
"id": 1,
"description": "Software Development",
"area_id": 1,
"area":
"id": 1,
"code": "01",
"description": "Headquarters"
,
],
"meta":
"success": true,
"count": 1
v2 数据(样本):
"data": [
"id": "1",
"type": "maint_service_nature",
"attributes":
"id": 1,
"description": "Software Development",
"area_id": 1
,
"relationships":
"area":
"data":
"id": "1",
"type": "area"
],
"included": [
"id": "1",
"type": "area",
"attributes":
"id": 1,
"code": "01",
"description": "Headquarters"
],
"meta":
"success": true,
"count": 1
我的模特:
Ext.define('Suite.model.MaintServiceNature',
extend: 'Ext.data.Model',
fields: [
desc: "Id", name: 'id', type: 'int', useNull: true ,
desc: "Area", name: 'area_id', type: 'int', useNull: true ,
desc: "Description", name: 'description', type: 'string', useNull: true, tableIdentification: true
],
associations: [
type: 'belongsTo',
model: 'Suite.model.Area',
foreignKey: 'area_id',
associationKey: 'area',
instanceName: 'Area',
getterName: 'getArea',
setterName: 'setArea',
reader:
type: 'json',
root: false
],
proxy:
type: 'rest',
url: App.getConf('restBaseUrlV2') + '/maint_service_natures',
reader:
type: 'json',
root: 'data',
record: 'attributes',
totalProperty: 'meta.count',
successProperty: 'meta.success',
messageProperty: 'meta.errors'
);
关于如何设置关联以处理 v2 数据的任何想法?
【问题讨论】:
我认为您将不得不推出自己的阅读器类...该框架未设置为处理这些类型的结构。 【参考方案1】:老实说,我正在尝试这个...我已经很多年没有使用过 Ext JS 4,而且我不会像 JSON:API 那样构建我的 JSON,但我认为你可以完成的唯一方法这是通过滚动您自己的reader
课程。鉴于您的数据结构具有通用属性,这个阅读器应该适用于所有场景......虽然,我对 JSON:API 不太熟悉,所以我可能完全错了。无论哪种方式,this 都是我想出的。
Ext.application(
name: 'Fiddle',
launch: function ()
Ext.define('MyReader',
extend: 'Ext.data.reader.Json',
alias: 'reader.myReader',
root: 'data',
totalProperty: 'meta.count',
successProperty: 'meta.success',
messageProperty: 'meta.errors',
/**
* @override
*/
extractData: function (root)
var me = this,
ModelClass = me.model,
length = root.length,
records = new Array(length),
dataConverter,
convertedValues, node, record, i;
for (i = 0; i < length; i++)
node = root[i];
var attrs = node.attributes;
if (node.isModel)
// If we're given a model instance in the data, just push it on
// without doing any conversion
records[i] = node;
else
// Create a record with an empty data object.
// Populate that data object by extracting and converting field values from raw data.
// Must pass the ID to use because we pass no data for the constructor to pluck an ID from
records[i] = record = new ModelClass(undefined, me.getId(attrs), attrs, convertedValues = );
// If the server did not include an id in the response data, the Model constructor will mark the record as phantom.
// We need to set phantom to false here because records created from a server response using a reader by definition are not phantom records.
record.phantom = false;
// Use generated function to extract all fields at once
me.convertRecordData(convertedValues, attrs, record, me.applyDefaults);
if (me.implicitIncludes && record.associations.length)
me.readAssociated(record, node);
return records;
);
Ext.define('Suite.model.Area',
extend: 'Ext.data.Model',
fields: [
name: 'type',
type: 'string'
]
);
Ext.define('Suite.model.MaintServiceNature',
extend: 'Ext.data.Model',
fields: [
desc: "Id",
name: 'id',
type: 'int',
useNull: true
,
desc: "Area",
name: 'area_id',
type: 'int',
useNull: true
,
desc: "Description",
name: 'description',
type: 'string',
useNull: true,
tableIdentification: true
],
associations: [
type: 'belongsTo',
model: 'Suite.model.Area',
associatedName: 'Area',
foreignKey: 'area_id',
associationKey: 'relationships.area.data',
instanceName: 'Area',
getterName: 'getArea',
setterName: 'setArea'
],
proxy:
type: 'rest',
url: 'data1.json',
reader:
type: 'myReader'
);
Suite.model.MaintServiceNature.load(null,
callback: function (record)
console.log(record.getData(true));
);
);
【讨论】:
感谢您抽出宝贵时间提供帮助。使用您的解决方案,我在该区域内的记录中有来自 data.relationships.area 的数据。但是如何从我记录的 Area 中的 area 类型的 included.attributes 中获取数据?例如,这是在网格上显示关系数据所必需的。 哦,对不起...这个结构太混乱了,我不明白你需要什么。我认为您必须取消 root 属性并设置在数据中查找位置的逻辑。以上是关于ExtJS 模型与 jsonapi 规范的关联的主要内容,如果未能解决你的问题,请参考以下文章