2009-08-17 12 views
8

Creo istanze di dijit.layout.ContentPane, dijit.layout.StackContainer e dijit.layout.BorderContainer dal mio codice JS.Quando devo chiamare il metodo startup() dei widget istanzialmente programmati?

Sembra che devo chiamare il metodo startup() di istanze create in modo programmato. Tuttavia, non sono sicuro di doverlo chiamare per ogni widget. Ad esempio, quando eseguo un 'new my.foo.widget()', lo startup() viene attivato automaticamente.

Grazie per avermi aiutato a capire quando chiamare il metodo startup()!

risposta

15

startup() è definito in _Widget ed è semplicemente una "parte del ciclo di vita". È l'ultimo passaggio nel ciclo di vita del widget e non è richiesto da tutti i widget. Il caso più comune in cui è assolutamente necessario è quando si creano programmaticamente widget di layout. È usato come un modo per prevenire i calcoli ridondanti quando i bambini hanno bisogno di dimensionamento. Ad esempio, un BorderContainer.

var bc = new dijit.layout.BorderContainer({ 
    style:"height:200px; width:200px" 
}); 

// can call bc.startup() now, and the BorderContainer will resize 
// all children each time a new child is added. Or, we can add all 
// our children now, then trigger startup() and do it all at once. 

var top = new dijit.layout.ContentPane({ 
    region:"top", style:"height:100px" 
}).placeAt(bc); 
var mid = new dijit.layout.ContentPane({ region:"center" }).placeAt(bc); 

// now BC will do the calculations, rather than in between each 
// the above addChild/placeAt calls. 
bc.startup(); 

avvio viene chiamato automaticamente dal parser in caso di parseOnLoad: vero o manuale esecuzione. Il parser ritarda la chiamata startup() fino a quando tutti i widget figli trovati non sono stati istanziati in modo appropriato.

dijit.Dialog è un caso strano. startup() DEVE essere chiamato anche su questo widget.

var dialog = new dijit.Dialog({ title:"Hmm", href:"foo.html" }); 
dialog.startup(); 
dialog.show(); 

La maggior parte dei widget NON richiedono startup chiamata, ma nei casi in cui qualcosa che eredita da _Widget non sostituisce il membro di avvio, la chiamata è essenzialmente un ambiente no-op this._started = true; Se crei la tua funzione startup(), dovresti chiamare this.inherited (argomenti) o semplicemente impostare il trigger _started manualmente.

In Dojo 1.4, il ciclo di vita qui è stato leggermente regolato.In precedenza, un widget con widgetInTemplate: true chiamava startup() sui widget figlio PRIMA dell'avvio() sul genitore. In 1.4 l'avvio dei bambini() sarà chiamato DOPO l'avvio genitore(). Questo comportamento è ricorsivo per molti livelli di widget nidificati con widgetInTemplate: true vengono istanziati.

È sempre "sicuro" chiamare .startup(), sebbene tu "sappia" (perché è un semplice widget endpoint o il tuo codice _Widget personalizzato) puoi omettere la chiamata.

+1

Solo per informazioni il comportamento reg dijit.Dialog è leggermente cambiato ora chiamando lo show chiama automaticamente l'avvio dall'interno della funzione – Gaurav

2

Sei sicuro che sia chiamato automaticamente o hai del codice nel tuo widget che lo chiama?

È buona norma chiamarlo poiché imposta _started su true che viene utilizzato da alcuni widget per determinare il comportamento e/o il layout. La maggior parte dei widget richiede che tu la chiami (come hai visto).

startup è molto utilizzato dai widget compositi che devono controllare i sub-widget.

Fondamentalmente, tutto ciò che eredita da dijit._Widget dovrebbe richiamare l'avvio dopo l'istanziazione.

Modifiche:

c'è un article on SitePen sul ciclo di vita dijit che discute avvio un po 'nell'articolo stesso e nei commenti. Ha più di due anni e penso che le cose siano cambiate.

Il O'Reilly dojo book parla anche di avvio ma dice che dovrebbe essere chiamato su widget containiner. Ho dovuto chiamarlo sulla griglia, anche se non ha senso.

Non fa male nulla chiamandolo (a meno che non lo chiami prima che i bambini vengano aggiunti al tuo widget). Direi sempre chiamarlo.

+0

Ho appena riprovato, e hai ragione. Anche per il mio widget, devo chiamare me stesso startup(). Gli esempi del Dojo Campus per dijit.layout.ContentPane (http://docs.dojocampus.org/dijit/layout/ContentPane) non chiamano il metodo startup(). Che mi dici di questo widget? – Philippe

+0

Hmm, hai ragione. Non sono sicuro del motivo per cui l'avvio non viene chiamato su quell'esempio. L'ho sempre chiamato per abitudine. – seth

0
startup (originating from dijit._Widget) 

Per i widget figli dichiarati in markup, questo metodo viene attivato automaticamente quando il widget e tutti i widget figli sono stati creati. In quanto tale, questo è il primo luogo sicuro in cui un widget figlio può fare riferimento in modo sicuro a un bambino. Per quanto semplice possa sembrare, questa attività è spesso tentata in postCreate, che può portare a comportamenti incoerenti che possono essere difficili da individuare e riparare. Per i widget creati a livello di codice che contengono altri widget secondari come parte di una relazione has-a, devi chiamare manualmente l'avvio manualmente quando sei sicuro che tutti i widget figli sono stati creati. Il motivo per cui è necessario chiamarlo personalmente per i widget creati a livello di codice che contengono i bambini è perché non avrebbe senso procedere con il ridimensionamento e il rendering, a meno che non siano stati aggiunti tutti i widget secondari. (Altrimenti, potrebbero esserci molte false partenze). Questo metodo è lo stub del metodo finale che è possibile sovrascrivere per il comportamento personalizzato che si verifica durante la costruzione di dijit.

Problemi correlati