2013-01-10 71 views

回答

70

對於澄清: 通過真正的類修改我的意思是一個打算永久 修改/擴展類,應該始終通過擴展一個類來完成的。 但它不是只是一個特定問題的臨時解決方案(錯誤修復等)

你至少有四個選項如何重寫的(EXT)類

  • 原型我猜是衆所周知的,允許您覆蓋成員一類的所有實例成員。您可以使用它像

    Ext.view.View.prototype.emptyText = ""; 
    

    雖然你不能使用它像

    // callParent is NOT allowed for prototype 
    Ext.form.field.Text.prototype.setValue = function(val) { 
        var me = this, 
         inputEl = me.inputEl; 
    
        if (inputEl && me.emptyText && !Ext.isEmpty(value)) { 
         inputEl.removeCls(me.emptyCls); 
         me.valueContainsPlaceholder = false; 
        } 
    
        me.callParent(arguments); 
    
        me.applyEmptyText(); 
        return me; 
    }; 
    

    這裏有一個JSFiddle

    這種變體不應該被用於實時類的修改。

  • Ext.override做幾乎一樣,那麼原型,但它完全適用於ExtJS的類系統,它允許您使用callParent()

    您可以使用它像

    // callParent is allowed for override 
    Ext.override('Ext.form.field.Text', { 
        setValue: function(val) { 
         this.callParent(['In override']); 
         return this; 
        } 
    }); 
    

    這裏有一個JSFiddle(cp錯誤已修復!感謝@nogridbag

    使用案例:我面臨的一個 RadioGroup中,其中ExtJS的期望對象(鍵 - 值對)正確 設定值的(我認爲還是存在的)的不良行爲。但我後端只有一個整數。 I 首先應用了一種修復方法,使用Ext.overridesetValue() 方法,然後從radiogroup擴展。在那裏,我只是從給定值中創建一個 鍵值對,然後用 調用父方法。

    由於@rixo提到這可以用於覆蓋實例成員。因此也可以勝任覆蓋甚至混入(我從來沒有測試它自己)

    var panel = new Ext.Panel({ ... }); 
    Ext.override(panel, { 
        initComponent: function() { 
         // extra processing... 
    
         this.callParent(); 
        } 
    }); 
    

    這種變體不應該被用於實時類的修改。

  • 擴展一個存在的類應用其他行爲&渲染。使用此變體創建一個行爲不同的子類型,而不會丟失原始類型。

    在下面的例子中,我們用一個方法延伸文本字段設置一個名爲setColored新值時改變labelcolor並重寫setValue方法採取去除標籤顏色的護理時setValue被直接稱爲

    Ext.define('Ext.ux.field.Text',{ 
        extend: 'Ext.form.field.Text', 
        widget: 'uxtextfield', 
        setColored: function(val,color) { 
         var me = this; 
         if (me.settedCls) { 
          me.removeCls(me.settedCls); 
         } 
         me.addCls(color); 
         me.settedCls = color; 
         me.setValue(val,true); 
        }, 
        setValue: function(val,take) { 
         var me = this; 
         if (!take && me.settedCls) { 
          me.removeCls(me.settedCls); 
         } 
         me.callParent(arguments); 
         return me; 
        } 
    }); 
    

    這裏的每個實例一個JSFiddle

  • 重寫將發生在極少數情況下,可能不適用於所有房產。在這種情況下(我手邊沒有例子),你需要一個不同的行爲,你可能會考慮重寫每個實例的設置。基本上,當你在類創建時應用配置時,你總是會這樣做,但大部分時間你只是覆蓋配置屬性的默認值,但你也可以覆蓋引用函數的屬性。這完全覆蓋了實現,並且您可能允許無法訪問基類型(如果存在),這意味着您不能使用callParent。您可以使用setValue來嘗試它,看看它不能應用於現有的鏈。但是,再次,您可能會遇到一些極其有用的罕見情況,即使它只是在開發過程中重新實現時也是如此。對於這種情況,您應該在使用Ext.override創建特定之後應用覆蓋,如上所述。

    重要:你不通過調用this如果你不使用Ext.override訪問類的實例!

如果我錯過了什麼什麼是(不再)是正確的,請評論或隨意編輯。

正如評論說@Eric

這些方法都允許您重寫混入(如Ext.form.field.Field)。由於mixin函數在您定義類時被複制到類中,因此您必須直接將覆蓋項應用於目標類

+0

@ A1rPun我做了一個編輯,我認爲解釋一切都好多了,更深一些 – sra

+0

哇,這比我要求的要多!謝謝! – A1rPun

+4

很好的答案,但我想提一個小警告。這些方法都不允許你重寫混入(比如'Ext.form.field.Field')。由於mixin函數在定義類時被複制到類中,因此您必須直接將覆蓋類應用於目標類。 – Eric

1

@sra的答案非常好,對我深入瞭解覆蓋分機可用的功能,但它不包括我最常實現覆蓋,看起來像這樣的方式:

Ext.define('my.application.form.field.Text' { 
    override: 'Ext.form.field.Text' 
    getValue: function() { 
     // your custom functionality here 
     arguments[1] = false; 

     // callParent can be used if desired, or the method can be 
     // re-written without reference to the original 
     this.callParent(arguments) 
    } 
}); 

我仍在使用分機5,所以我會再加載此文件在我Application.js並將其添加到需要的數組,從而將覆蓋應用於全局應用程序。我認爲Ext 6項目包含覆蓋文件夾,只需將該文件添加到該文件夾​​即可確保應用覆蓋。

+0

Thx作爲詳細的解釋和例子。 – CharanRoot