Javascript ExtJS 5:父模型转换对子关联的依赖

Javascript ExtJS 5:父模型转换对子关联的依赖,javascript,extjs,extjs5,Javascript,Extjs,Extjs5,我有两个模型。。。父母和孩子。。。父对象有许多子模型。在Child中,我有一个字段,它是使用其数据创建的(在本例中,它只是转换并返回1)。在父级中,我有两个转换正在进行。。。一个使用它的数据,第二个依赖于孩子的数据。但是,在创建父模型时,子关联似乎尚未完全烘焙,但当我使用新值更新父模型时,子关联就在那里 基本上,我想知道的是,当您看到Total2控制台启动时,我希望填充测试。在父级中使用转换函数之前,如何强制读取关联?理想情况下,如果子级发生更改,父级中的依赖转换函数将自动启动。。。我意识到这很

我有两个模型。。。父母和孩子。。。父对象有许多子模型。在Child中,我有一个字段,它是使用其数据创建的(在本例中,它只是转换并返回1)。在父级中,我有两个转换正在进行。。。一个使用它的数据,第二个依赖于孩子的数据。但是,在创建父模型时,子关联似乎尚未完全烘焙,但当我使用新值更新父模型时,子关联就在那里

基本上,我想知道的是,当您看到Total2控制台启动时,我希望填充测试。在父级中使用转换函数之前,如何强制读取关联?理想情况下,如果子级发生更改,父级中的依赖转换函数将自动启动。。。我意识到这很可能是不可能的,但这将是一个难以置信的额外奖励

这是我的

app.js

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);
    }
},