Why is it that Ext.form.Field's setValue does not fire an event to notify listeners it's value has changed? I know there is the change
and select
event for combobox but these only fire events on user interaction, what about when another component changes the value of a field? Let me explain by a situation i'm facing atm.
I'm currently working on a reusable fieldset component (lets call it ux.fieldset) with a combobox and another fieldset inside. The inner fieldset should be hidden/shown based on the selected value of the combobox.
I've registered a listener on the combobox which listens to the select
event and when it fires just evaluates the selected value and show/hides the inner fieldset.
Then I add this ux.fieldset as a component to one of my forms.
Now when I do a loadRecord() on the form I would like the value of the inner combobox be re-evaluated so I can show/hide the inner fieldset of my component. The code that does this evaluation should obviously be in the ux.fieldset since that contains the combobox and since it's reusable it would be wise to put it there (DRY).
Is there a preferred or better way to handle this scenario? I've pasted the code of my ux below in case anyone is confused by my explanation above.
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', Ex开发者_开发技巧t.ux.form.StatusFieldSet);
UPDATE:
I've managed to work it out by overloading the setValue method on the combobox instance. But it's by no means an elegant nor good solution if you ask me.
this.combo.setValue = function(v){
this.showOnPending(v);
return Ext.form.ComboBox.superclass.setValue.apply(this.combo, arguments);
}.createDelegate(this);
I would like to get some input from ExtJS veterans, how they would handle it.
Yep, setValue
doesn't fire any events. I can only speculate as to why. I can tell you that You are stepping on any functionality that Combo
adds to setValue
with your work around though.
Something like this would be safer.
this.combo.setValue = this.combo.setValue.createSequence(this.showOnPending, this);
There is also some code out there that will 'fix' setValue
so it fires an event. I'll try to find it. It adds a second parameter to setValue. You could override Combo.prototype.setValue
using Ext.override
with it: http://code.extjs.com:8080/ext/ticket/185.
In the end I think creating the sequence is still your safest bet.
Adding a change event to a combobox's setValue
method is fairly easy using an override class:
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)
}
}
You'll just need to make sure that file containing this code gets loaded by the application. I'm still using Ext 5 so I add it to the requires array of the project's Application.js
file, but I believe Ext 6 has an override folder and simply placing this file there ensures that it's loaded.
精彩评论