2011-10-05 5 views
12

sto lavorando con backbone.js costruzione di alcuni complessi visualizzare le relazioni, e mi chiedo se ci sono problemi dal punto di vista una performance JavaScript di fare qualcosa che assomiglia a questo:Nesting Vista all'interno Vista a spina dorsale js

var viewOne = Backbone.View.extend({ 
     tagName : 'li', 
     initialize : function() { 
       this.v2 = new viewTwo({parent:this}); 
     }, 
     clickHideOne : function() { 
       $(this.el).removeClass('selected'); 
     } 
}); 

var viewTwo = Backbone.View.extend({ 
     tagName : 'a', 
     initialize : function() { 
       this.bind('click', this.clickHide, this); 
     }, 
     clickHide(){ 
       $(this.el).removeClass('selected'); 
       this.options.parent.clickHideOne(); 
     } 
}); 

Dove questo è un esempio molto semplice di un riferimento circolare tra due viste, in modo che eventi in una vista possano propagarsi facilmente lungo una catena di viste o mantenere qualsiasi riferimento agli oggetti nelle viste principali. Ci sono situazioni in cui questo sarebbe un problema, in particolare in relazione alle potenziali perdite con riferimenti agli elementi DOM in IE7 +, oppure esiste un'altra best practice raccomandata per referenziare le viste genitore.

Inoltre, ho capito che potevo semplicemente fare $ (this.el) .parent ('li'). RemoveClass ('selected'); in vista, non è questo il punto ... questo è solo un esempio molto semplice della domanda che ho sul riferimento circolare.

risposta

15

Avere una vista genitore responsabile per le visualizzazioni figlio non è una cattiva idea ed è piuttosto uno scenario comune in backbone. Il problema che vedo con il codice sopra è il fatto che la vista figlio ha una conoscenza della sua vista genitore. Vorrei suggerire di utilizzare eventi personalizzati nella viewTwo e avere viewOne eseguire il binding a tali eventi e quindi rispondere di conseguenza.

Questo è abbastanza semplice con backbone utilizzando il metodo trigger() e il metodo bind().

+0

Questo suona come un buon metodo, suppongo che mi stia chiedendo anche perché sarebbe stato specificamente dannoso per la vista figlio avere una conoscenza della vista genitore? – tgriesser

+3

Poiché l'oggetto figlio non è responsabile della creazione dell'oggetto padre, non dovrebbe esserne a conoscenza ed essere completamente indipendente. In pratica stai creando dipendenze non necessarie. –

+1

Ma non avrebbe senso se ci fosse una dipendenza dall'oggetto genitore ... come se l'oggetto figlio non potesse esistere senza l'oggetto genitore - e che si potesse semplicemente cambiare quale oggetto era il "genitore" della vista piuttosto di dover ridefinire i binding e gli inneschi – tgriesser

0

L'annidamento è un buon metodo per mantenere viste gerarchiche per la scrittura di codice gestibile per interfacce utente complesse. Nel semplice esempio ci sono pochissimi problemi di prestazioni, ma in situazioni più complesse è necessario tenere a mente la profondità del nesting. Ad esempio, l'utilizzo di renderer di celle complessi in modo errato in una griglia di migliaia di righe potrebbe rendere inutilizzabile l'applicazione. In questi casi, di solito si possono fare intelligenti ottimizzazioni, ad es. utilizzando i renderer solo per le celle della griglia visibili.

2

I riferimenti circolari sono una cattiva idea. Inoltre, non è una buona pratica, come ha detto Kyle, che una vista da bambino abbia un riferimento esplicito alla sua vista genitoriale. I riferimenti espliciti dovrebbero andare verso il basso solo nella gerarchia della vista. Vale a dire, è normale, e tipico, che una vista genitoriale abbia riferimenti espliciti a tutte le sue viste secondarie e che invochi i metodi delle viste secondarie per interagire con esse. (Vedere il mix Backbone.Subviews per ogni modo di creare e gestire viste secondarie). Tuttavia, la migliore pratica di incapsulamento impone che una vista non abbia mai riferimenti espliciti o chiama direttamente i metodi dei suoi fratelli o dei suoi genitori.

Al fine di comunicare con i fratelli o genitori, avete tre opzioni che sono a conoscenza di:

  1. Usa view.trigger() per attivare un evento sulla vista del bambino (o un fratello), e poi avere il genitore (o fratello) ascolta quell'evento usando view.listenTo(). Questo approccio funziona ma inizia a scomparire quando si desidera che una vista secondaria comunichi con suo nonno, ecc. Inoltre, si creano dipendenze esplicite non necessarie se si utilizza questo approccio con i fratelli.

  2. È possibile utilizzare Backbone.Courier, che è un plug-in che consente di semplificare gli eventi nella gerarchia della vista. Per la comunicazione tra le visualizzazioni di pari livello, un fratello bolle un evento fino al genitore e quindi il genitore chiama direttamente un metodo dell'altro fratello.

  3. È possibile utilizzare uno event aggregator per agire come oggetto intermedio tra figlio e genitore o tra fratelli. In questo modo queste viste possono comunicare attraverso l'aggregatore, senza riferimenti espliciti l'uno con l'altro.Tuttavia, questo approccio richiede oggetti aggregatori globali e consente anche un incrocio di dipendenze implicite, che può diventare difficile da gestire con l'aumentare del numero di visualizzazioni.

+0

Queste 3 opzioni sono ottime per gestire le comunicazioni tra le viste ... ma mi chiedo solo se ho una vista "A" che ha viste secondarie e una di esse chiama una modale, quando la modale è finita si innesca. La modale interrompe la gerarchia, quindi dovrei usare Event Aggregator per la mia vista 'A' lo ascolta? – mateusmaso