Почему Ext.form.Field.setValue () не запускает событие? Как это "исправить"? - PullRequest
7 голосов
/ 24 января 2011

Почему setValue в Ext.form.Field не запускает событие, чтобы уведомить слушателей, что его значение изменилось?Я знаю, что для выпадающего списка есть события change и select, но они только запускают события при взаимодействии с пользователем, что делать, когда другой компонент изменяет значение поля?Позвольте мне объяснить ситуацию, с которой я сталкиваюсь.

В настоящее время я работаю над повторно используемым компонентом набора полей (назовем его ux.fieldset) с комбинированным списком и другим набором полей внутри.Внутренний набор полей должен быть скрыт / показан в соответствии с выбранным значением поля со списком.Я зарегистрировал прослушиватель в выпадающем списке, который прослушивает событие select, а при его запуске просто оценивает выбранное значение и показывает / скрывает внутренний набор полей.

Затем я добавляю этот ux.fieldset в качестве компонентав одной из моих форм.

Теперь, когда я выполняю loadRecord () в форме, я бы хотел, чтобы значение внутреннего комбинированного списка было переоценено, чтобы я мог показать / скрыть внутренний набор полей моего компонента.Код, который выполняет эту оценку, очевидно, должен быть в наборе ux.field, поскольку он содержит комбинированный список, и, поскольку его можно использовать повторно, было бы разумно поместить его туда (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);

ОБНОВЛЕНИЕ:

Мне удалось решить его путем перегрузкиметод setValue в экземпляре комбинированного списка.Но это ни в коем случае не элегантное и не хорошее решение, если вы спросите меня.

this.combo.setValue = function(v){
    this.showOnPending(v);
    return Ext.form.ComboBox.superclass.setValue.apply(this.combo, arguments);
}.createDelegate(this);

Я хотел бы получить некоторую информацию от ветеранов ExtJS, как они справятся с этим.

Ответы [ 2 ]

3 голосов
/ 24 января 2011

Да, 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.

В конце концов, я думаю, что создание последовательности по-прежнему является вашей самой безопасной ставкой.

0 голосов
/ 26 мая 2017

Добавление события изменения к методу 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, поэтому я добавляю его в массив require файла проекта Application.js, но я считаю, что Ext 6 имеет папку переопределения, и простое размещение этого файла гарантирует его загрузку.

...