2012-03-31 1 views
13

Ho una visualizzazione principale che contiene alcune visualizzazioni secondarie sulla pagina, quando navigo verso un'altra pagina utilizzando il router, come posso pulire le viste esistenti e creare nuove viste per la pagina a cui voglio navigare?Backbone JS: come ripulire le viste quando si naviga verso un altro url?

Questa applicazione non ha modelli/collezioni, solo viste.

Grazie!

Parte del codice:

Home = Backbone.View.extend({ 
    template: "static/js/templates/home.html", 

    initialize: function() { 
     _.bindAll(this); 
     this.render(); 
    }, 

    render: function() { 
     var view = this; 

     // Fetch the template, render it to the View element and call done. 
     namespace.fetchTemplate(this.template, function(tmpl) { 
     view.el.innerHTML=tmpl(); 
     view.subRender(); 
     }); 

     return this; 
    }, 
    subRender: function() { 
     var view = this; 
     var videoView = new Subview1({ 
     el: $('#wrapper1'), 
     homeView: view 
     }); 
     var timeView = new Subview2({ 
     el: $("#wrapper2") 
     }); 
    } 
}); 
+0

Sembra una soluzione migliore. – user469652

risposta

9

Probabilmente si potrebbe semplicemente utilizzare il meccanismo degli eventi di backbone per farlo se si desidera.

Avresti solo bisogno di creare un router di eventi globale, e poi avere ciascuna delle tue visualizzazioni per ascoltare un evento CloseView. Quindi devi solo eseguire tutti gli arresti alla ricezione dell'evento CloseView.

var dispatcher = _.clone(Backbone.Events) 

Home = Backbone.View.extend({ 
    ... 
    initialize: function() { 
     ... 
     dispatcher.on('CloseView', this.close, this); 
    } 
    close: function() { 
     // Unregister for event to stop memory leak 
     dispatcher.off('CloseView', this.close, this); 
     this.remove(); 
     this.unbind(); 
     this.views = []; // Clear the view array 
    } 
    ... 
}); 

SubView = Backbone.View.extend({ 
    ... 
    initialize: function() { 
     ... 
     dispatcher.on('CloseView', this.close, this); 
    } 
    close: function() { 
     // Unregister for event to stop memory leak 
     dispatcher.off('CloseView', this.close, this); 
     // Do other close stuff here. 
    } 
}); 

Poi è solo un caso di chiamare dispatcher.trigger('OnClose') nel router/altrove per attivare le funzioni stretti.

Come scorciatoia, supponendo di voler eseguire questo arresto su ogni navigazione, è sufficiente registrare gli eventi sul router (un evento personalizzato 'OnClose' come qui, o l'evento 'tutti' per ottenere solo ogni navigazione) anche se dovresti stare attento che gli eventi sono stati chiamati nell'ordine che ti aspettavi.

Probabilmente sarebbe anche possibile refactoring alcuni di questo codice in Backbone.View.prototype o simile, ma lascerò che qualcun altro a fare.

+0

Ho adottato e mi è piaciuto ora. – user469652

+0

posso chiederti perché non lo faresti su ogni percorso? e perché stai cancellando i punti di vista []? – pushplaybang

+0

anche view.stopListening() apparentemente è ora chiamato autimaticamente su view.remove - quindi il precedente è ancora rilevante? - i metodi di eventi personalizzati hanno senso, ma dovremmo eseguire la chiusura in modo diverso ora? – pushplaybang

4

devo conservare sub-viste in un array e quando chiudo un -view "genitore", tramite la funzione della vista close(), iterare l'array e chiudo la sub- visualizzazioni.

Ciò richiede Subview1 e Subview2 per avere anche le funzioni close().

Home = Backbone.View.extend({ 
    template: "static/js/templates/home.html", 

    initialize: function() { 
     _.bindAll(this); 
     this.render(); 
     // Hold sub views 
     this.views = []; 
    }, 
    close: function() { 
     this.remove(); 
     this.unbind(); 
     this.clear_views(); 
    }, 
    clear_views: function() { 
     while this.views.length > 0 
     this.views[0].close() 
     this.views.splice(0, 1) 
    }, 
    render: function() { 
     var view = this; 

     // Fetch the template, render it to the View element and call done. 
     namespace.fetchTemplate(this.template, function(tmpl) { 
     view.el.innerHTML=tmpl(); 
     view.subRender(); 
     }); 

     return this; 
    }, 
    subRender: function() { 
     var view = this; 
     var videoView = new Subview1({ 
     el: $('#wrapper1'), 
     homeView: view 
     }); 
     this.views.push(videoView); 
     var timeView = new Subview2({ 
     el: $("#wrapper2") 
     }); 
     this.views.push(timeView); 
    } 
}); 
+0

Grazie, a proposito, possiamo aggiungere il close() a Backbone.View.prototype. Attualmente sto facendo questo in modo simile, ma cerco una soluzione più elegante. – user469652