2011-01-24 2 views
7

Почему функция setValue Ext.form.Field не запускает событие, чтобы уведомить слушателей о его изменении? Я знаю, что есть событие change и select для combobox, но это только события пожара при взаимодействии с пользователем, а что, когда другой компонент меняет значение поля? Позвольте мне объяснить ситуацию, с которой я столкнулся.Почему Ext.form.Field.setValue() не запускает событие? Как его «исправить»?

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

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

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

UPDATE:

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

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

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

+0

Расширение comboBox для прослушивания специальных прослушиваний? (Или, может быть, я неправильно прочитал нить? Повторное чтение .. :) –

+0

Я бы предпочел не расширять Combobox для этой тривиальной проблемы ... кажется, что-то, что должно быть намного легче исправить без подкласса снова – ChrisR

+0

Я спросил вопрос и получил ответ, который, я считаю, также может ответить на ваш вопрос: «Никакие события пользовательского интерфейса не запускаются с использованием JavaScript. Это делается для предотвращения бесконечных циклов и других нежелательных побочных эффектов при взаимодействии со страницей программно ». http://stackoverflow.com/questions/4591625/what-is-a-good-way-of-filling-a-form-in-extjs-by-code-and-fire-the-events-for- ea –

ответ

3

Yep, 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

Я пробовал createInterceptor, но не пробовал createSequence ... дайте мне попробовать! Спасибо за идею. – ChrisR

+0

Спасибо, что работает ... Мне удалось заставить его работать с createInterceptor тоже ... я забыл присвоить значение экземпляру combobox ... спасибо большое! – ChrisR

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, но я считаю, что Ext 6 имеет переопределяющую папку, и просто поместить этот файл там гарантирует, что он загружен.

Смежные вопросы