Esta es una gran pregunta. La columna vertebral es excelente debido a la falta de suposiciones que hace, pero significa que debe (decidir cómo) implementar cosas como esta usted mismo. Después de revisar mis propias cosas, descubro que (más o menos) uso una combinación de escenario 1 y escenario 2. No creo que exista un cuarto escenario mágico porque, simplemente, todo lo que haces en los escenarios 1 y 2 debe ser hecho.
Creo que sería más fácil explicar cómo me gusta manejarlo con un ejemplo. Digamos que tengo esta página simple dividida en las vistas especificadas:

Digamos que el HTML es, después de ser renderizado, algo como esto:
<div id="parent">
<div id="name">Person: Kevin Peel</div>
<div id="info">
First name: <span class="first_name">Kevin</span><br />
Last name: <span class="last_name">Peel</span><br />
</div>
<div>Phone Numbers:</div>
<div id="phone_numbers">
<div>#1: 123-456-7890</div>
<div>#2: 456-789-0123</div>
</div>
</div>
Esperemos que sea bastante obvio cómo el HTML coincide con el diagrama.
El ParentViewsostiene 2 vistas secundarias, InfoViewy PhoneListViewasí como algunos divs adicionales, uno de los cuales, #name, se debe establecer en algún momento. PhoneListViewcontiene vistas secundarias propias, una serie de PhoneViewentradas.
Entonces a su pregunta real. Manejo la inicialización y el renderizado de manera diferente según el tipo de vista. Divido mis puntos de vista en dos tipos, Parentpuntos de vista y Childpuntos de vista.
La diferencia entre ellos es simple, las Parentvistas tienen vistas secundarias mientras que las Childvistas no. Entonces, en mi ejemplo, ParentViewy PhoneListViewson Parentvistas, while InfoViewy las PhoneViewentradas son Childvistas.
Como mencioné antes, la mayor diferencia entre estas dos categorías es cuando se les permite renderizar. En un mundo perfecto, quiero que las Parentvistas solo se muestren una vez. Depende de sus vistas secundarias manejar cualquier representación cuando los modelos cambien. Childvistas, por otro lado, permito volver a renderizar en cualquier momento que lo necesiten, ya que no tienen ninguna otra vista que se base en ellas.
En un poco más de detalle, para las Parentvistas me gusta que mis initializefunciones hagan algunas cosas:
- Inicializar mi propia vista
- Render mi propio punto de vista
- Cree e inicialice las vistas secundarias.
- Asigne a cada vista secundaria un elemento dentro de mi vista (por ejemplo,
InfoViewse le asignaría #info).
El paso 1 se explica por sí mismo.
El paso 2, la representación, se realiza para que los elementos en los que se basan las vistas secundarias ya existan antes de que intente asignarlos. Al hacer esto, sé que todos los niños eventsestarán configurados correctamente, y puedo volver a renderizar sus bloques tantas veces como quiera sin preocuparme de tener que volver a delegar nada. En realidad, no veo renderningún punto de vista infantil aquí, les permito que lo hagan dentro de los suyos initialization.
Los pasos 3 y 4 se manejan realmente al mismo tiempo que paso elal crear la vista secundaria. Me gusta pasar un elemento aquí, ya que siento que el padre debe determinar dónde, según su propia opinión, el niño puede poner su contenido.
Para la representación, trato de mantenerlo bastante simple para las Parentvistas. Quiero que la renderfunción no haga nada más que representar la vista principal. Sin delegación de eventos, sin representación de vistas secundarias, nada. Solo un simple render.
Sin embargo, a veces esto no siempre funciona. Por ejemplo, en mi ejemplo anterior, el #nameelemento deberá actualizarse cada vez que cambie el nombre dentro del modelo. Sin embargo, este bloque es parte de la ParentViewplantilla y no es manejado por una Childvista dedicada , así que evito eso. Crearé algún tipo de subRenderfunción que solo reemplace el contenido del #nameelemento, y no tenga que desechar todo el #parentelemento. Esto puede parecer un truco, pero realmente he descubierto que funciona mejor que tener que preocuparme por volver a representar todo el DOM y volver a conectar elementos y demás. Si realmente quisiera hacerlo limpio, crearía una nueva Childvista (similar a la InfoView) que manejaría el #namebloque.
Ahora, para las Childvistas, initializationes bastante similar a las Parentvistas, solo que sin la creación de más Childvistas. Entonces:
- Inicializar mi vista
- La configuración se vincula a la escucha de cualquier cambio en el modelo que me interesa
- Render mi punto de vista
ChildLa visualización de renderizado también es muy simple, solo renderiza y configura el contenido de mi el. Una vez más, no te metas con la delegación ni nada de eso.
Aquí hay un código de ejemplo de cómo se ParentViewpuede ver mi :
var ParentView = Backbone.View.extend({
el: "#parent",
initialize: function() {
// Step 1, (init) I want to know anytime the name changes
this.model.bind("change:first_name", this.subRender, this);
this.model.bind("change:last_name", this.subRender, this);
// Step 2, render my own view
this.render();
// Step 3/4, create the children and assign elements
this.infoView = new InfoView({el: "#info", model: this.model});
this.phoneListView = new PhoneListView({el: "#phone_numbers", model: this.model});
},
render: function() {
// Render my template
this.$el.html(this.template());
// Render the name
this.subRender();
},
subRender: function() {
// Set our name block and only our name block
$("#name").html("Person: " + this.model.first_name + " " + this.model.last_name);
}
});
Puedes ver mi implementación de subRenderaquí. Al tener cambios vinculados en subRenderlugar de render, no tengo que preocuparme por volar y reconstruir todo el bloque.
Aquí hay un código de ejemplo para el InfoViewbloque:
var InfoView = Backbone.View.extend({
initialize: function() {
// I want to re-render on changes
this.model.bind("change", this.render, this);
// Render
this.render();
},
render: function() {
// Just render my template
this.$el.html(this.template());
}
});
Los enlaces son la parte importante aquí. Al vincularme a mi modelo, nunca tengo que preocuparme de llamarme manualmente render. Si el modelo cambia, este bloque se volverá a representar sin afectar ninguna otra vista.
El PhoneListViewserá similar a la ParentView, usted sólo necesita un poco más de la lógica, tanto en sus initializationy renderfunciones a las colecciones de la manija. La forma en que maneja la colección depende de usted, pero al menos deberá escuchar los eventos de la colección y decidir cómo desea renderizar (agregar / eliminar o simplemente volver a renderizar todo el bloque). Personalmente, me gusta agregar nuevas vistas y eliminar las viejas, no volver a renderizar toda la vista.
El PhoneViewserá casi idéntico al InfoViewsólo escuchar a los cambios en el modelo que se preocupa.
Espero que esto haya ayudado un poco, avíseme si algo es confuso o no está lo suficientemente detallado.