2013-06-05 6 views

Antwort

9

Diese Methode ist ähnlich ein constructor für Komponenten. Es wird durch die wahre constructor aufgerufen, und ist ein wirklich guter Hook-Punkt, um die Initialisierung der Komponente anzupassen (wie im Namen gesagt!).

Außer in einigen sehr seltenen Fällen sollten Sie initComponent anstelle der constructor außer Kraft setzen, da die grundlegendere Initialisierung bereits stattgefunden hat. Vor allem wurde das config-Objekt, das an den Konstruktor übergeben wurde, bereits in das Objekt eingefügt.

Angenommen, Sie möchten die Konfiguration einer Komponente anpassen, z. B. width. Wenn Sie dies im Konstruktor versuchen, müssen Sie zuerst prüfen, ob ein Konfigurationsobjekt übergeben wurde oder nicht (um zu vermeiden, dass Sie versuchen, eine Eigenschaft auf undefined zu setzen), und Sie haben das config-Objekt überschrieben Das ist schlechte Praxis. Wenn Sie die Option in this festlegen, kann dies vom Konfigurationsobjekt überschrieben werden. Wenn Sie den Wert im Konfigurationsobjekt ändern, ändern Sie das Objekt und brechen die Erwartungen des aufrufenden Codes (d. H. Die Wiederverwendung des Konfigurationsobjekts führt zu einem unerwarteten Ergebnis). In initComponent wird der Wert immer this.width sein, Sie müssen sich nicht um die Konfiguration kümmern.

Ein weiterer interessanter Punkt ist, dass initComponent der Ort ist, wo untergeordnete Komponenten (für Container), speichert, Ansicht, Vorlagen usw. erstellt werden. Bevor Sie also die Superklassenmethode initComponent aufrufen, können Sie darauf reagieren und sicherstellen, dass sie nicht bereits verwendet oder benötigt wurden (z. B. Hinzufügen von Elementen, Erstellen des Geschäfts usw.). Auf der anderen Seite, sobald Sie die Super-Methode aufgerufen haben, werden Sie garantiert, dass all diese Abhängigkeiten erstellt und instanziiert wurden. Das ist also der richtige Ort, um beispielsweise Listener zu Abhängigkeiten hinzuzufügen.

Beachten Sie, dass in initComponent kein Rendering stattfindet. Untergeordnete Komponenten werden erstellt und konfiguriert, aber ihre DOM-Elemente wurden nicht erstellt. Um die Wiedergabe zu beeinflussen, werden Sie verwenden, haben ähnliche Ereignisse zu machen oder suchen Sie nach den afterRender oder onRender Methoden ...

Hier ist eine illustrierte Zusammenfassung:

constructor: function(config) { 

    // --- Accessing a config option is very complicated --- 

    // unsafe: this may be changed by the passed config 
    if (this.enableSomeFeature) { ... } 

    // instead, you would have to do: 
    var featureEnabled; 
    if (config) { // not sure we've been passed a config object 
     if (Ext.isDefined(config.featureEnabled)) { 
      featureEnabled = config.featureEnabled; 
     } else { 
      featureEnabled = this.enableSomeFeature; 
     } 
    } else { 
     featureEnabled = this.enableSomeFeature; 
    } 
    // now we know, but that wasn't smooth 
    if (featureEnabled) { 
     ... 
    } 


    // --- Even worse: trying to change the value of the option --- 

    // unsafe: we may not have a config object 
    config.enableSomeFeature = false; 

    // unsafe: we are modifying the original config object 
    (config = config || {}).enableSomeFeature = false; 

    // cloning the config object is safe, but that's ineficient 
    // and inelegant 
    config = Ext.apply({enableSomeFeature: false}, config); 


    // --- Super method --- 

    this.callParent(arguments); // don't forget the arguments here! 

    // -------------------- 

    // here initComponent will have been called 
} 

,initComponent: function() { 

    // --- Accessing config options is easy --- 

    // reading 
    if (this.enableSomeFeature) { ... } 

    // or writing: we now we change it in the right place, and 
    // we know it has not been used yet 
    this.deferRender = true; 


    // --- Completing or changing dependant objects is safe --- 
    // items, stores, templates, etc. 

    // Safe: 
    // 1. you can be sure that the store has not already been used 
    // 2. you can be sure that the config object will be instantiated 
    // in the super method 
    this.store = { 
     type: 'json' 
     ... 
    }; 


    // --- However that's too early to use dependant objects --- 

    // Unsafe: you've no certitude that the template object has 
    // already been created 
    this.tpl.compile(); 


    // --- Super method --- 

    this.callParent(); 

    // -------------------- 


    // Safe: the store has been instantiated here 
    this.getStore().on({ 
     ... 
    }); 


    // will crash, the element has not been created yet 
    this.el.getWidth(); 
}