ExtJS:字段更改事件在 ViewController 的初始化之前触发

ExtJS: Field change event fires before ViewController's init

我有一个有状态的字段,我也将它连接到更改事件...当它的值发生变化时,我想执行一些操作。然而,因为它是一个有状态的字段,所以当我回到这个视图时会触发 change 事件,不幸的是,change 事件在 ViewController 的 init 方法之前触发,这意味着我将无法访问我的引用查找。

在下面的示例中,运行 它,更改日期,然后重新运行 应用程序...您将看到一个 console.log 出现的更改,然后是初始化。我意识到我可以在 init 方法中设置处理程序,但这看起来很愚蠢。我还意识到我可以将 myField 创建为私有变量并以这种方式访问​​它,但这似乎也很愚蠢。是的,我可以更改为 select 事件,但这不是我想要做的。有人有什么想法吗?这是一个 example:

Ext.application({
    name : 'Fiddle',

    launch : function() {
        Ext.state.Manager.setProvider(new Ext.state.CookieProvider());
        Ext.define('MyViewController', {
            extend: 'Ext.app.ViewController',
            alias: 'controller.myView',

            init: function() {
                console.log('init fired', this.lookupReference('myField'))
            },

            onChange: function(value) {
                console.log('onChange fired', this.lookupReference('myField'));
            }
        });
        Ext.define('MyView', {
            extend: 'Ext.container.Container',
            controller: 'myView',
            renderTo: Ext.getBody(),
            items: [{
                xtype: 'datefield',
                value: new Date(),
                stateful: true,
                stateId: 'blahblah',
                listeners:{
                    change: 'onChange'
                }
            }, {
                xtype: 'datefield',
                value: new Date(),
                reference: 'myField'
            }]
        });
        Ext.create('MyView');
    }
});

这是因为状态混合在控制器之前初始化,这是直接从Ext.Component的构造函数中获取的代码:

    me.mixins.state.constructor.call(me);
    me.addStateEvents('resize');
    controller = me.getController();
    if (controller) {
        controller.init(me);
    }

没有更改此行为的配置。老实说,我从未见过有人将表单字段的值设置为有状态的。

您可以使用 buffer 配置来延迟事件触发。 这具有在控制器初始化后设置事件的优点。

解决方法:

listeners: {
    change: {
      buffer: 300,
      fn: 'onChange'
    }
}

另一种方法是处理有状态字段的“beforestaterestore”事件,并仅在控制器初始化后应用状态值。

listeners: {
  beforestaterestore: function (field, state){
     var controller = field.up().getController();

     Ext.Function.interceptAfter(controller, 'init', function(){
       field.setValue(state.value); // update
     },this);

     return false;
  }
}