2011-10-05 14 views
12

estoy trabajando con Backbone.js la construcción de algunas complejas relaciones de vista, y me pregunto si hay algún problema desde un punto de vista el rendimiento de JavaScript de hacer algo que se parece a esto:Vistas de anidamiento dentro de Vistas en backbone.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(); 
     } 
}); 

Donde este es un ejemplo muy simple de una referencia circular entre dos vistas, para que los eventos en una vista se propaguen fácilmente por una cadena de vistas o mantengan referencias a los objetos en las vistas principales. ¿Hay alguna situación en la que esto sería un problema, específicamente en relación con las posibles filtraciones con referencias de elementos DOM en IE7 +, o hay otra práctica recomendada recomendada para hacer referencia a las vistas principales?

Además, entiendo que solo podría hacer $ (this.el) .parent ('li'). RemoveClass ('selected'); en vista Dos, ese no es el punto ... esto es solo un ejemplo muy simple de la pregunta que tengo sobre la referencia circular.

Respuesta

15

Tener una vista principal responsable de las vistas secundarias no es una mala idea y es un escenario bastante común en la red troncal. El problema que veo con el código anterior es el hecho de que la vista hija tiene conocimiento de su vista principal. Sugeriría usar eventos personalizados en viewTwo y tener viewOne vinculado a esos eventos y luego responder en consecuencia.

Esto es bastante fácil con la red troncal mediante el método trigger() y el método bind().

+0

Parece un buen método, supongo que también me pregunto por qué sería especialmente dañino para la vista secundaria tener conocimiento de la vista principal. – tgriesser

+3

Como el objeto secundario no es responsable de la creación del objeto primario, no debería tener conocimiento de él y ser completamente independiente. Básicamente estás creando dependencias innecesarias. –

+1

Pero, ¿no tendría sentido si hubiera una dependencia en el objeto principal ... como si el objeto hijo no pudiera existir sin el objeto principal, y que pudieras simplemente cambiar qué objeto era el "padre" de la vista en lugar de que tener que volver a definir los enlaces y disparadores – tgriesser

0

El anidamiento es una buena forma de mantener vistas jerárquicas para escribir código mantenible para interfaces de usuario complejas. En el ejemplo simple, casi no hay problemas de rendimiento, pero en situaciones más complejas, debe tener en cuenta qué tan profunda es su anidación. Por ejemplo, el uso incorrecto de procesadores de células complejos en una cuadrícula de miles de filas puede hacer que la aplicación quede inutilizable. En tales casos, se pueden hacer optimizaciones inteligentes, por ejemplo. usando renderizadores solo para las celdas visibles de la grilla.

2

Las referencias circulares son una mala idea. Tampoco es una buena práctica, como dijo Kyle, que una vista hija tenga una referencia explícita a su vista principal. Las referencias explícitas deben ir ABAJO la jerarquía de vista solamente. Es decir, está bien, y es típico, que una vista principal tenga referencias explícitas a todas sus vistas secundarias y que invoque métodos de vistas secundarias para interactuar con ellas. (Consulte Backbone.Subviews mixin para cada forma de crear y administrar vistas secundarias). Sin embargo, la mejor práctica de encapsulación dicta que una vista nunca debe tener referencias explícitas o directamente llamar directamente a los métodos de sus hermanos o sus padres.

Con el fin de comunicarse con los hermanos o padres, usted tiene tres opciones que yo sepa:

  1. Uso view.trigger() para activar un evento en la vista del niño (o hermanos), y luego tener la matriz (o hermano) escuchen ese evento usando view.listenTo(). Este enfoque funciona pero comienza a descomponerse cuando desea que una vista hija se comunique con su abuelo, etc. También crea dependencias explícitas innecesarias si usa este enfoque con sus hermanos.

  2. Puede usar Backbone.Courier, que es un complemento que facilita el burbujeo de eventos en la jerarquía de vistas. Para la comunicación entre vistas de hermanos, un hermano burbujea un evento hasta el padre, y luego el padre llama directamente a un método del otro hermano.

  3. Puede usar un event aggregator para actuar como un objeto intermedio entre el niño y el padre, o entre los hermanos. De esta forma, estas vistas se pueden comunicar a través del agregador, sin referencias explícitas entre sí.Sin embargo, este enfoque requiere objetos agregadores globales, y también permite el cruce de dependencias implícitas, que pueden ser difíciles de administrar a medida que crece el número de vistas.

+0

Estas 3 opciones son geniales para manejar las comunicaciones entre vistas ... pero me pregunto en un caso que tengo una vista "A" que tiene vistas secundarias y una de ellas llama a modal, cuando el modal termina, se dispara. El modal rompe la jerarquía, entonces debería usar Event Aggregator para mi vista 'A' ¿Lo escucha? – mateusmaso

Cuestiones relacionadas