2011-01-24 15 views
7

爲什麼Ext.form.Field的setValue不會觸發事件來通知監聽器其值已更改?我知道對於組合框有changeselect事件,但這些僅在用戶交互時觸發事件,當另一個組件更改字段的值時,該怎麼辦?讓我來解釋一下我面臨的問題。Ext.form.Field.setValue()爲什麼不觸發事件?如何「修復」它?

我目前正在研究一個可複用的fieldset組件(可以稱之爲ux.fieldset),裏面有一個組合框和另一個fieldset。應該根據組合框的選定值隱藏/顯示內部字段集。 我已經在組合框中註冊了一個偵聽器,該組件偵聽select事件,並且它觸發時只評估選定的值並顯示/隱藏內部字段集。

然後我將這個ux.fieldset作爲一個組件添加到我的一個表單中。

現在,當我在窗體上執行loadRecord()時,我希望重新評估內部組合框的值,以便可以顯示/隱藏組件的內部字段集。 做這個評估的代碼顯然應該在ux.fieldset中,因爲它包含組合框,並且因爲它是可重用的,所以將它放在那裏是明智的(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); 

UPDATE:

我已經成功通過重載的ComboBox實例setValue方法去解決它。但是,如果你問我,這絕不是一個優雅而又不錯的解決方案。

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

我想從ExtJS老兵那裏得到一些輸入,他們如何處理它。

+0

擴展組合框有特殊的監聽器嗎? (或者,也許我誤讀了線程?重新閱讀.. :) – 2011-01-24 13:00:51

+0

我寧願避免延長Combobox這個微不足道的問題...似乎應該很容易修復,而不需要繼續子類化 – ChrisR 2011-01-24 14:23:12

回答

3

是的,setValue不會觸發任何事件。我只能推測爲什麼。我可以告訴你,你正在使用任何功能CombosetValue增加你的工作,雖然。

這樣的事情會更安全。

this.combo.setValue = this.combo.setValue.createSequence(this.showOnPending, this); 

還有一些代碼將'修復'setValue因此它觸發了一個事件。 我會盡力找到它。 它將第二個參數添加到setValue。您可以用Ext.override覆蓋Combo.prototype.setValuehttp://code.extjs.com:8080/ext/ticket/185

最後我認爲創建序列仍然是最安全的選擇。

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文件的require數組中,但我相信Ext 6有一個覆蓋文件夾,只需將該文件放置在那裏以確保它已加載。

相關問題