2012-05-18 8 views
7

¿Es posible tener una plantilla anidada dentro de una plantilla y acceder mediante la vista de red troncal?plantilla de red troncal anidada en otra plantilla

Por ejemplo, tengo View1 usando Template1, y View2 usando Template2. Template2 realmente necesita estar en un DIV dentro de Template1. Puse el contenedor DIV para template2 dentro de template1 con el id apropiado, pero no se muestra cuando se procesa la página. Si elimino el contenedor div de Template2 desde Template1 y lo coloco en el cuerpo de la página, funciona bien.

Me pregunto si esto es posible, o si tengo que anidar las vistas/modelos, etc. para que esto funcione.

Los datos en la Plantilla 2 no están técnicamente relacionados con la Plantilla 1, solo tiene que mostrarse en una posición en la página que está incrustada en la Plantilla1.

+0

¿Puede compartir algún código? –

+0

Sé que esto no responde a su pregunta, pero Ember js es compatible con algo parecido. Puede definir recursos anidados ... que sorta le permite anidar plantillas dentro de las plantillas. http://emberjs.com/guides/routing/defining-your-routes/ –

Respuesta

20

La forma en que he tratado esto en el pasado es definir ambas vistas por separado, y luego cuando renderiza View1, crea una nueva View2, la renderiza e inserta en View1. Por lo tanto:

window.View1 = Backbone.View.extend({ 
    render: function() { 
     this.view2 = new View2(); 
     this.$('insert-view-here').append(this.view2.render().el); 
    } 
}); 
+0

Esto funcionó, gracias. – mbr1022

+1

En este caso, ¿cómo se maneja el cambio del elemento interno? ¿Siempre renderizas desde arriba hacia abajo, puede el elemento interior cambiarse de alguna manera? –

+0

Los cambios en los elementos internos se pueden manejar desde la segunda vista, del mismo modo que los manejaría en cualquier otra situación.Si, por alguna razón, la vista principal o el modelo cambia y requiere que se vuelva a procesar el html, las vistas secundarias se recrearán dentro de este método de renderizado. – RTigger

0

La forma típica como yo lo entiendo, es pensar en vistas como objetos completos que se pueden incrustar en el otro. Supongamos que tiene dos vistas, ViewA y ViewB. El siguiente código muestra cómo puede agregar ViewB a ViewA.

# this is coffeescript, but it's easily translated to JS 
class ViewA extends Backbone.View 
    initialize:() -> 
     this.render() 

    render:()-> 
     this.$el.append(new ViewB().$el) 
     this.$el.append(new ViewB().$el) 
     return this 

Se puede conseguir la suposición con la forma de gestionar ViewB (asignarlo a propiedades o lo que sea) o pasar diferentes argumentos de constructor en cada instancia ViewB.

4

Debe crear subvistas para esto.

Me gusta privatizar las subvistas en el cierre y devolver la vista del público.

var View = (function (BV) { 
    var View, Subview; 

    // Only this main view knows of this subview 
    Subview = BV.extend({ 
     template: _.template(subtmpl), 

     render: function() { 
      this.$el.html(this.template(this.model.toJSON())); 
      return this; 
     } 
    }); 

    View = BV.extend({ 
     template: _.template(tmpl), 

     render: function() { 
      this.$el.html(this.template(this.model.toJSON())); 

      var subview = new SubView({ model: this.model }); 

      // replace a div in your template meant for teh subview with the real subview 
      this.$el.find("#subview").replaceWith(subview.render().el); 

      return this; 
     } 
    }); 

    return View; 

}(Backbone.View)); 

var view = new View({ model: user }); 
var subview = new Subview; // Reference Error 
2

Otra opción que es útil cuando se necesita para incluir Template2 varias veces dentro de Plantilla1, dicen que <li> elementos dentro de un <ul>, consiste en pasar una función Template2 en Plantilla1. (De Rico Sta Cruz' Backbone Patterns.)

TasksList = Backbone.View.extend({ 
    // Template1, inlined in js. 
    template: _.template([ 
    "<ul class='task_list'>", 
     "<% items.each(function(item) { %>", 
     "<%= itemTemplate(item) %>", 
     "<% }); %>", 
    "</ul>" 
    ].join('')), 

    // Template2, inlined in js. 
    itemTemplate: _.template(
    "<li><%= name %></li>" 
), 

    render: function() { 
    var html = this.template({ 
     items: tasks /* a collection */, 
     itemTemplate: this.itemTemplate 
    }); 

    $(this.el).append(html); 
    } 
}); 
0

Una solución más magra y sin la necesidad de jQuery append() o el objeto subvista adicional que implica un alcance doble jQuery, es para pre-hacer/precompilación estrictamente utilizando el método de subrayado, e insertar la subvista como una cadena, usando una etiqueta de comentario interno en su plantilla principal.

View = Backbone.View.extend({ 
    template: _.template(...), 
    prerender: function(tpl,model){// pre-render a component 
     var template = _.template(tpl); 
     return template(model); 
    }, 
    render: function(){ 
    var model = { ... }; 
    var component = this.prerender(this.itemTemplate, model); 
    this.$el.html(this.template(model).replace('<!--#component-->', component)); 
    } 
}); 

Es especialmente útil si su plantilla no es una constante, y depende de una propiedad del alcance actual.

Teniendo en cuenta que para el alcance de esta pregunta, debe pasar el modelo de View2 al componente.

Cuestiones relacionadas