Javascript ExtJS 5:父模型转换对子关联的依赖
我有两个模型。。。父母和孩子。。。父对象有许多子模型。在Child中,我有一个字段,它是使用其数据创建的(在本例中,它只是转换并返回1)。在父级中,我有两个转换正在进行。。。一个使用它的数据,第二个依赖于孩子的数据。但是,在创建父模型时,子关联似乎尚未完全烘焙,但当我使用新值更新父模型时,子关联就在那里 基本上,我想知道的是,当您看到Total2控制台启动时,我希望填充测试。在父级中使用转换函数之前,如何强制读取关联?理想情况下,如果子级发生更改,父级中的依赖转换函数将自动启动。。。我意识到这很可能是不可能的,但这将是一个难以置信的额外奖励 这是我的 app.jsJavascript ExtJS 5:父模型转换对子关联的依赖,javascript,extjs,extjs5,Javascript,Extjs,Extjs5,我有两个模型。。。父母和孩子。。。父对象有许多子模型。在Child中,我有一个字段,它是使用其数据创建的(在本例中,它只是转换并返回1)。在父级中,我有两个转换正在进行。。。一个使用它的数据,第二个依赖于孩子的数据。但是,在创建父模型时,子关联似乎尚未完全烘焙,但当我使用新值更新父模型时,子关联就在那里 基本上,我想知道的是,当您看到Total2控制台启动时,我希望填充测试。在父级中使用转换函数之前,如何强制读取关联?理想情况下,如果子级发生更改,父级中的依赖转换函数将自动启动。。。我意识到这很
Ext.application({
name : 'Fiddle',
launch : function() {
var store = Ext.create('Ext.data.Store', {
model: 'Namespace.model.Parent',
autoLoad: true,
listeners: {
load: onLoadStore
}
});
var grid = Ext.create('Ext.grid.Panel', {
title: 'associations',
store: store,
renderTo: Ext.getBody(),
columns: [{
text: 'Primary Key',
dataIndex: 'PrimaryKey'
}]
});
function onLoadStore(store, records, successful, eOpts) {
var firstGroups = store.first().getGroupsStore();
console.log('before', firstGroups.getCount(), firstGroups.isLoaded());
firstGroups.first().set('GroupName', 'blah');
store.first().set('blank', 1)
}
}
});
家长
Ext.define('Namespace.model.Parent', {
extend: 'Ext.data.Model',
alias: 'model.parent',
requires: [
'Ext.data.field.Integer',
'Ext.data.field.String',
'Namespace.model.Child'
],
idProperty: "PrimaryKey",
fields: [{
type: 'string',
name: 'PrimaryKey',
critical: true
}, {
type: 'string',
name: 'Title'
}, {
type: 'int',
name: 'Rating',
defaultValue: 2
}, {
type: 'int',
name: 'Total',
depends: ['Rating'],
convert: function(value, record) {
console.log('Total', record)
return record.get('Rating') * 2;
}
}, {
name: 'Total2',
type: 'int',
depends: ['groupsMapping', 'blank'],
// depends on child's Test property
convert: function(value, record) {
var groupsMapping = record.get('groupsMapping');
if (groupsMapping) {
for (var i = 0; i < groupsMapping.length; i++) {
console.log('Total2', groupsMapping[i].GroupName, groupsMapping[i].Test);
}
}
return 0;
}
}, {
name: 'groupsMapping',
type: 'auto',
mapping: 'Groups'
}, {
name: 'blank',
type: 'int'
}],
hasMany: [{
model: 'Namespace.model.Child',
associationKey: 'Groups',
name: 'getGroupsStore'
}],
proxy: {
type: 'ajax',
url: 'data1.json'
}
});
我遇到了同样的问题,花了一些时间才意识到这些关联在转换时不可用 就像在您的示例中一样,我将子记录与父记录(嵌套)一起发送,并使用子模型和父字段子数据“手动”构建了一个假存储,以便对转换/计算进行数学计算,这实现了以下目的:
{
name: 'validationScore',
depends: ['childRecords'],
type: 'number',
persist: false,
convertOnSet: true,
convert: function(val, rec){
// here we have access only to direct record field, and not the association association !
// we can use data directly in the calculation
children = rec.get('childRecords');
// or build a fake store in order to easily parse them
children = Ext.create('Ext.data.Store', {
model: 'Namespace.model.ChildModel',
data: rec.get('childRecords')
})
// ... calculate whatever
return result;
}
}
但现在我的“新”挑战是找到一个(好的)解决方案,根据子记录的更改更新转换后的值…我做了一些类似于qdev的事情,只是听了实际协会的存储。不过构造器有点怪。。。如果我没有把超时放在那里,那么我会在尝试访问存储加载中的第一条记录时出错。。。可能是一个框架错误,或者我正在做一些可怕的事情。重要的代码是构造函数和计算方法。。。在应用程序中,更改子数据时我只有1秒的超时。。。您可以看到网格的行数据从3更改为102。以下是更新的:
{
name: 'validationScore',
depends: ['childRecords'],
type: 'number',
persist: false,
convertOnSet: true,
convert: function(val, rec){
// here we have access only to direct record field, and not the association association !
// we can use data directly in the calculation
children = rec.get('childRecords');
// or build a fake store in order to easily parse them
children = Ext.create('Ext.data.Store', {
model: 'Namespace.model.ChildModel',
data: rec.get('childRecords')
})
// ... calculate whatever
return result;
}
}
constructor: function(config) {
this.callParent(arguments);
var me = this;
setTimeout(function() {
var groupsStore = me.getGroupsStore();
if (groupsStore) {
groupsStore.on('update', me.calculateChanges, me);
groupsStore.on('datachanged', me.calculateChanges, me);
}
me.calculateChanges();
}, 1);
},
calculateChanges: function() {
console.log('calculating');
var groupsStore = this.getGroupsStore();
if (groupsStore) {
var total2 = 0;
groupsStore.each(function(group) {
total2 += group.get('Test');
});
this.set('Total2', total2);
}
},