2012-03-31 14 views
13

Tengo una vista de inicio que contiene algunas subvistas en la página, cuando navego a otra página usando el enrutador, ¿cómo puedo limpiar las vistas existentes y construir nuevas vistas para la página que quiero navegar?Backbone JS: cómo limpiar vistas cuando navegas a otra url?

Esta aplicación no tiene modelos/colecciones, solo visualizaciones.

¡Gracias!

parte del código:

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

Suena una mejor solución. – user469652

Respuesta

9

Probablemente pueda utilizar el mecanismo de eventos de la red troncal para hacer esto si lo desea.

Solo necesita crear un enrutador de eventos global, y luego hacer que cada una de sus vistas escuche un evento CloseView. Entonces solo necesita realizar todo el apagado al recibir el 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. 
    } 
}); 

Entonces es sólo un caso de llamar dispatcher.trigger('OnClose') en su router/otro lugar para activar las funciones de cierre.

Como atajo, suponiendo que deseara realizar este apagado en cada navegación, puede registrar eventos en el enrutador (ya sea un evento 'OnClose' personalizado como aquí o el evento 'todos' para obtener cada navegación) aunque tendrías que tener cuidado de que los eventos fueron llamados en el orden que esperabas.

Probablemente también sea posible refactorizar parte de este código en Backbone.View.prototype o similar, pero lo dejaré para que lo haga otra persona.

+0

Adopté, y me gustó ahora. – user469652

+0

¿Puedo preguntar por qué no haría esto en cada ruta? y por qué estás despejando las vistas []? – pushplaybang

+0

también view.stopListening() aparentemente ahora se llama autimatically en view.remove - ¿así que lo anterior sigue siendo relevante? - los métodos de eventos personalizados tienen sentido, pero ¿w debería estar ejecutando el cierre de forma diferente ahora? – pushplaybang

4

almaceno sub-puntos de vista en una matriz y cuando cierro un -view "padre", a través de la función de la vista close(), iterar sobre la matriz y cierro la sub- puntos de vista.

Esto requiere que Subview1 y Subview2 tengan también las funciones 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

Gracias, por cierto, podemos agregar close() a Backbone.View.prototype. Actualmente estoy haciendo esto de una manera similar, pero busco una solución más elegante. – user469652

Cuestiones relacionadas