underscore source examples backbonejs backbone annotated backbone.js

backbone.js - source - Al cambiar el modelo para una vista, ¿es mejor reemplazar el modelo o crear una nueva vista?



underscore js download (3)

Tengo una vista de correo electrónico en mi aplicación Backbone. Actualmente está instanciado en la acción de view de mi controlador. Va un poco como esto:

routes: { ''email/:id'': email }, //... email: function (id) { var email = new Email({ id: id }); this.emailView = new EmailView({ model: email }); email.fetch(); }

Ahora, el problema es que si visito un correo electrónico y luego otro, termino creando dos EmailView separado. Esto significa que, por ejemplo, el enlace de eliminación en EmailView está vinculado a dos modelos de Email separados, por lo que al hacer clic en eliminar se eliminarán ambos (no es bueno).

Estoy mirando dos soluciones. En uno, caché el EmailView y actualizo su modelo. El problema entonces es que tendría que volver a enlazar los events en EmailView .

La otra solución sería crear un nuevo EmailView como lo soy en este momento, pero desenlazar los eventos del viejo EmailView.el antes de reemplazarlo.

¿Voy a hacer esto de la manera correcta? ¿Hay una mejor manera de manejar esta situación? Saludos de antemano.


Cree una instancia de vista separada para cada instancia de modelo. Cada vez que visita un nuevo correo electrónico, deseche la vista anterior y cree una nueva vista con la nueva instancia de correo electrónico.

Probablemente lo que tienes si estoy adivinando es una vista de lista en el lado izquierdo y un editor a la derecha. Selecciona el correo electrónico de la lista de la izquierda y desea que el cuerpo del correo electrónico aparezca a la derecha.

Realmente quieres unas 5 clases de vista.

PageView has_one EmailCollectionView on left has_one EmailEditorView on right EmailCollectionView has_many EmailSummaryViews as vertical list EmailEditorView has_one EmailView centered

Al hacer clic en EmailCollectionView, se activa un evento que es recogido por EmailEditorView, que desecha su antigua instancia de EmailView y presenta una nueva versión de EmailView.

Algo así de todos modos.


Creo que los controladores de eventos DOM deben eliminarse mediante una llamada al método remove () de la vista; consulte http://api.jquery.com/remove (que Backbone llama debajo de las cubiertas)

Si reemplaza el método remove () para eliminar también el enlace a cualquier evento del modelo, como JohnnyO sugirió, la recolección de basura debe hacerse cargo de la eliminación de la vista.

Terminé haciendo el reemplazo del método remove () para manejar esto:

class EmailView extends Backbone.View initialize: () -> @model.bind(''change'', @render) render: () => # do some stuff remove: () -> @model.unbind(''change'', @render) super()

A continuación, puede utilizar como tal en un enrutador:

routes: ''email/:id'': email //... email: (id) -> var email = new Email({ id: id }); this.emailView.remove() if this.emailView this.emailView = new EmailView({ model: email }); email.fetch(); }

Esto funcionará asumiendo que todos los eventos en la vista están vinculados al elemento correcto, es decir, que está usando @el (o this.el) en la Vista y que cada vista tiene su propio @ el / this.el.


Originalmente, estábamos creando nuevos objetos de vista cada vez que alguien navegaba, por ejemplo, por "candidatos / show", como en el ejemplo del correo electrónico. Esa vista vinculó un controlador al evento ''reset'' de su modelo persistente . Cuando luego reiniciamos ese modelo desde la línea de comandos, veríamos que se activan tantos eventos como instancias de esa vista. En otras palabras, esa vista no estaba siendo recogida de basura, a pesar de que todos los elementos que agregó al DOM fueron completamente destruidos.

Nuestra solución fue simplemente asegurarnos de instanciar nuestras vistas de nivel superior una vez, y luego hacer que las vistas de sus hijos se realicen en sus métodos de inicialización. Luego simplemente vuelva a renderizarlos según sea necesario. Entonces no tiene que preocuparse por la complejidad de la recolección de basura (que, por lo que sé por nuestros experimentos, no sucede de todos modos).