为什么Ext.form.Field的setValue不会触发事件来通知侦听器它的值已经改变了?我知道组合框有change
和select
事件,但这些只会触发用户交互事件,当另一个组件更改字段值时会怎样?让我解释一下我面临的一个局面。
我目前正在研究一个可重用的fieldset组件(让我们称之为ux.fieldset),其中包含一个组合框和另一个字段集。应根据组合框的选定值隐藏/显示内部字段集。
我在组合框上注册了一个侦听器,它监听select
事件,当它触发时,只评估所选值并显示/隐藏内部字段集。
然后我将这个ux.fieldset作为一个组件添加到我的一个表单中。
现在,当我在表单上执行loadRecord()时,我希望重新计算内部组合框的值,这样我就可以显示/隐藏组件的内部字段集。 执行此评估的代码显然应该在ux.fieldset中,因为它包含组合框,因为它可以重复使用,所以将它放在那里(DRY)是明智的。
是否有首选或更好的方法来处理此方案?我已经粘贴了下面的ux代码,以防有人对我上面的解释感到困惑。
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);
更新:
我设法通过在combobox实例上重载setValue方法来解决这个问题。但如果你问我,这绝不是一个优雅的解决方案。
this.combo.setValue = function(v){
this.showOnPending(v);
return Ext.form.ComboBox.superclass.setValue.apply(this.combo, arguments);
}.createDelegate(this);
我想从ExtJS老手那里获得一些意见,他们将如何处理它。
答案 0 :(得分:3)
是的,setValue
不会触发任何事件。我只能推测为什么。我可以告诉您,虽然您正在踩着Combo
添加到setValue
的任何功能。
这样的事情会更安全。
this.combo.setValue = this.combo.setValue.createSequence(this.showOnPending, this);
还有一些代码会“修复”setValue
,因此它会触发一个事件。 我会试着找到它。它为setValue添加了第二个参数。您可以使用Combo.prototype.setValue
覆盖Ext.override
:http://code.extjs.com:8080/ext/ticket/185。
最后,我认为创建序列仍然是最安全的选择。
答案 1 :(得分:0)
使用覆盖类将更改事件添加到组合框的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 5,所以我将它添加到项目的Application.js
文件的requires数组中,但我相信Ext 6有一个覆盖文件夹,只需将此文件放在那里就可以确保它&# 39; s loading。