2013-01-10 11 views

risposta

70

Per maggiore chiarezza: Con reale modificazione classe intendo permanente modifica/estensione prevista di una classe, che deve sempre essere fatto estendendo una classe. Ma non è una soluzione temporanea per un problema specifico (bug-fix, ecc.) .

di avere almeno quattro opzioni come ignorare i membri della (EXT) Classi

  • prototipo Credo che è ben noto e consente di sostituire un membro per tutte le istanze di una classe. Si può usare come

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

    Anche se non è possibile utilizzarlo come

    // 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; 
    }; 
    

    Ecco un JSFiddle

    Questa variante non deve essere utilizzato per le modifiche vera classe.

  • Ext.override fa quasi lo stesso, allora prototipo ma si applica pienamente alla ExtJS Class-sistema che consente di utilizzare callParent()

    è possibile utilizzarlo come

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

    Ecco un JSFiddle (errore cp corretto! Grazie a @nogridbag)

    Caso d'uso: Ho affrontato un cattivo comportamento (credo tuttora esistente) di un RadioGroup dove ExtJS aspettarsi un oggetto (chiave-valore-coppia) per il corretto impostazione del valore. Ma ho solo un intero sul mio back-end. I per prima cosa ha applicato una correzione utilizzando Ext.override per il metodo setValue() e successivamente si estende da radiogruppo. Lì faccio una coppia chiave-valore dal valore dato e chiamo il metodo genitore con .

    Come @rixo menzionato questo può essere utilizzato per superiori un membro di istanza.E può quindi essere qualificato per superiori anche mixins (non ho mai provato io stesso)

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

    Questa variante non deve essere usato per le modifiche vera classe.

  • Estendere una classe esistente per applicare comportamento aggiuntivo & rendering. Usa questa variante per creare un sottotipo che si comporta diversamente senza perdere il tipo originale.

    Nel seguente esempio si estendono il campo di testo con un metodo per modificare la LabelColor quando si imposta un nuovo valore denominato setColored e sovrascrivere il metodo setValue di prendersi cura di rimuovere un colore di etichetta quando setValue è chiamato direttamente

    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; 
        } 
    }); 
    

    Ecco un Overriding JSFiddle

  • per istanza accadrà in casi davvero rari e potrebbe non essere applicabile a tutte le proprietà. In tal caso (dove non ho un esempio in mano) hai una sola necessità di un comportamento diverso e potresti prendere in considerazione l'ipotesi di sovrascrivere un'impostazione solo per istanza. Fondamentalmente si fanno tali cose tutte le volte che si applica una configurazione sulla creazione della classe, ma quasi sempre si sostituiscono i valori predefiniti delle proprietà di configurazione, ma si è anche in grado di sovrascrivere le proprietà che fanno riferimento alle funzioni. Questo completamente sovrascrive l'implementazione e potresti consentire di non avere accesso al tipo di base (se esiste) che significa che non puoi usare callParent. Potresti provare con setValue per vedere che non può essere applicato a una catena esistente. Ma ancora, potresti affrontare alcuni rari casi in cui ciò è utile, anche quando è solo in fase di sviluppo e viene reimplementato per essere produttivo. In tal caso, è necessario applicare l'override dopo aver creato lo specifico utilizzando Ext.override come indicato sopra.

    Importante: Non si dispone di accesso alla classe istanza richiamando this se non si utilizza Ext.override!

Se ho perso qualcosa o qualcosa è (più) corretto, si prega di lasciare un commento, o si sentono libero di modificarla.

come commentato da @Eric

Nessuno di questi metodi consentono di ignorare mixins (come Ext.form.field.Field).Poiché le funzioni di mixin sono copiate in classi al momento della definizione della classe, è necessario applicare direttamente le sostituzioni alle classi di destinazione

+0

@ A1rPun Ho fatto una modifica che penso spieghi tutto un po 'meglio e più in profondità – sra

+0

Wow, questo è più di quanto ho chiesto! Grazie! – A1rPun

+4

Ottima risposta, ma c'è un piccolo avvertimento che voglio menzionare. Nessuno di questi metodi ti consente di ignorare i mixin (come 'Ext.form.field.Field'). Poiché le funzioni di mixin sono copiate in classi nel momento in cui si definisce la classe, è necessario applicare direttamente le sostituzioni alle classi di destinazione. – Eric

1

La risposta di @sra è ottima ed è stata molto utile per me ottenere una comprensione più profonda della ridefinire le funzionalità disponibili in Ext, ma non include il modo in cui ho più comunemente implementare le sostituzioni che sembra qualcosa di simile:

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) 
    } 
}); 

sto ancora utilizzando Ext 5 quindi vorrei caricare questo file nel mio Application.js e aggiungilo all'array richiede lì che applica l'override all'app a livello globale. Penso che i progetti di Ext 6 includano una cartella di override e che semplicemente aggiungendo questo file in quella cartella si assicuri che l'override sia applicato.

+0

Thx per una spiegazione dettagliata e un esempio. – CharanRoot