Events 为什么Ext.form.Field.setValue()不触发事件?如何";“固定”;信息技术

Events 为什么Ext.form.Field.setValue()不触发事件?如何";“固定”;信息技术,events,combobox,extjs,listener,Events,Combobox,Extjs,Listener,为什么Ext.form.Field的setValue没有触发事件来通知侦听器它的值已更改?我知道combobox有change和select事件,但这些事件只会在用户交互时触发,那么当另一个组件更改字段的值时呢?让我来解释一下我面临的情况 我目前正在开发一个可重用的字段集组件(我们称之为ux.fieldset),其中包含一个组合框和另一个字段集。应根据组合框的选定值隐藏/显示内部字段集。 我在组合框上注册了一个侦听器,它侦听select事件,当它触发时,只计算所选值并显示/隐藏内部字段集 然后我

为什么Ext.form.Field的setValue没有触发事件来通知侦听器它的值已更改?我知道combobox有
change
select
事件,但这些事件只会在用户交互时触发,那么当另一个组件更改字段的值时呢?让我来解释一下我面临的情况

我目前正在开发一个可重用的字段集组件(我们称之为ux.fieldset),其中包含一个组合框和另一个字段集。应根据组合框的选定值隐藏/显示内部字段集。 我在组合框上注册了一个侦听器,它侦听
select
事件,当它触发时,只计算所选值并显示/隐藏内部字段集

然后我将这个ux.fieldset作为一个组件添加到我的一个表单中

现在,当我在表单上执行loadRecord()时,我希望重新计算内部组合框的值,以便显示/隐藏组件的内部字段集。 执行此评估的代码显然应该在ux.fieldset中,因为它包含combobox,并且因为它是可重用的,所以明智的做法是将它放在那里(DRY)

有没有更好的方法来处理这种情况?我在下面粘贴了我的用户体验代码,以防有人被我上面的解释弄糊涂

Ext.ux.form.StatusFieldSet = Ext.extend(Ext.form.FieldSet, {
     enablePublishFrom      : false // Wether or not the option to (un)publish on a certain date should be visible, defaults to false
    ,item_store             : false
    ,combo                  : false
    ,date_publish           : false
    ,date_unpublish         : false
    ,helpBox                : {
         xtype              : 'box'
        ,autoEl             : {cn: 'Help text<br />'}
    }
    ,publishData_fieldset   : false
    ,datePickerWidth        : 60 // The width of the datepickers in the subfieldset

    ,initComponent : function(){

        this.item_store = [['online',  _('Gepubliceerd')]]; // Online
        if(this.enablePublishFrom) {this.item_store.push(['pending', _('Publiceer op datum')]);} // Publish on date
        this.item_store.push(['offline', _('Niet gepubliceerd')]); // Offline

        this.combo = new Ext.form.ComboBox({
             name           : 'status'
            ,hideLabel      : true
            ,displayField   : 'txt'
            ,valueField     : 'quicklink'
            ,hiddenName     : 'status'
            ,value          : 'online'
            ,forceSelection : true
            ,allowBlank     : false
            ,editable       : false
            ,triggerAction  : 'all'
            ,mode           : 'local'
            ,store          : new Ext.data.SimpleStore({
                 fields     : [ 'quicklink', 'txt' ]
                ,data       : this.item_store
            })
            ,listeners      : {
                 scope      : this
                ,select     : function(combo, value, index) {   // HERE I would like to add another listener that gets triggered when another value is selected or set through setValue()
                    this.showOnPending(value.data.quicklink);
                }
            }
        });

        this.date_publish = new Ext.form.DateField({
             fieldLabel : _('Publiceer op')
            ,name       : 'publish_date'
            ,format     : 'd-m-Y'
            ,width      : this.datePickerWidth
        });

        this.date_unpublish = new Ext.form.DateField({
             fieldLabel : _('De-publiceer op')
            ,name       : 'unpublish_date'
            ,format     : 'd-m-Y'
            ,width      : this.datePickerWidth
        });

        this.publishData_fieldset = new Ext.form.FieldSet({
             autoHeight         : true
            ,hidden             : true
            ,anchor             : '0'
            ,defaults           : {
                 labelSeparator : ''
                ,anchor         : '0'
            }
            ,items              : [ this.helpBox, this.date_publish, this.date_unpublish ]
        });

        // Config with private config options, not overridable
        var config = {
             items      : [ this.combo, this.publishData_fieldset ]
            ,title      : _('Status')
            ,autoHeight : true
        };

        Ext.apply(this, Ext.apply(this.initialConfig, config));

        Ext.ux.form.StatusFieldSet.superclass.initComponent.call(this, arguments);

    }

    ,showOnPending: function(v) {
        if(v == 'pending'){
            this.publishData_fieldset.show();
        } else {
            this.publishData_fieldset.hide();
        }
    }
});

Ext.reg('statusfieldset', Ext.ux.form.StatusFieldSet);

我想从ExtJS的老手那里得到一些信息,他们将如何处理它。

是的,
setValue
不会触发任何事件。我只能猜测原因。我可以告诉您,您正在使用
Combo
添加到
setValue
中的任何功能

像这样的东西会更安全

this.combo.setValue = this.combo.setValue.createSequence(this.showOnPending, this);
还有一些代码将“修复”
setValue
,因此它会触发一个事件。我会努力找到它的。它向setValue添加第二个参数。您可以使用
Ext.override
覆盖
Combo.prototype.setValue


最后,我认为创建序列仍然是最安全的选择。

使用覆盖类将更改事件添加到组合框的
setValue
方法相当容易:

Ext.define('<app_name>.override.form.field.ComboBox', {
    override: 'Ext.form.field.ComboBox',
    setValue(newValue) {
        let oldValue = this.getValue();
        this.callParent(arguments);
        this.fireEvent('change', this, newValue, oldValue)
    }
}
Ext.define('.override.form.field.ComboBox'{
重写:“Ext.form.field.ComboBox”,
设置值(新值){
让oldValue=this.getValue();
this.callParent(参数);
this.firevent('change',this,newValue,oldValue)
}
}

您只需确保包含此代码的文件已被应用程序加载。我仍在使用Ext 5,因此我将其添加到项目的
application.js
文件的requires数组中,但我相信Ext 6有一个覆盖文件夹,只需将此文件放在那里即可确保已加载。

扩展组合框以具有特殊的这方面的听众?(或者可能是我误读了这条线索?重新阅读:)我更愿意避免为这个琐碎的问题扩展Combobox…似乎不需要对againI进行子类化就可以更容易地修复。我问了一个问题,得到了一个回答,我相信这也可以回答您的问题:“JavaScript不会触发任何UI事件。这是为了防止在集成时出现无休止的循环和其他不希望的副作用。”是的,但是setValue不是一个UI事件,它是一个组件事件。可能“select”或“change”不是在该点触发的正确事件,但应该有一些内容来监听值的更改。是“valuechanged”还是“valueset”…现在什么都没有了。我试过createInterceptor,但没有试过createSequence…让我试一下!谢谢你的想法。谢谢,这很有效…我也设法让它与createInterceptor一起工作了…我忘了将值赋回combobox实例…非常感谢!
Ext.define('<app_name>.override.form.field.ComboBox', {
    override: 'Ext.form.field.ComboBox',
    setValue(newValue) {
        let oldValue = this.getValue();
        this.callParent(arguments);
        this.fireEvent('change', this, newValue, oldValue)
    }
}