2012-05-18 14 views
7

Czy jest możliwe umieszczenie szablonu zagnieżdżonego w szablonie i dostęp przez widok szkieletu?Szablon szkieletowy zagnieżdżony w innym szablonie

Na przykład mam View1 za pomocą Template1 i View2 za pomocą Template2. Template2 musi znajdować się w DIV wewnątrz Template1. Umieściłem kontener DIV dla szablonu2 wewnątrz szablonu1 z odpowiednim identyfikatorem, ale nie pokazuje się, kiedy strona jest renderowana. Jeśli usuwam element div Template2 z wnętrza Template1 i po prostu umieszczam go w treści strony, to działa dobrze.

Zastanawiasz się, czy to jest możliwe, czy też muszę zagnieżdżać widoki/modele itp., Aby to działało?

Dane w Template2 nie są powiązane merytorycznie z Template1 po prostu trzeba wyświetlić w pozycji na stronie osadzonej w Template1.

+0

Czy możesz udostępnić kod? –

+0

Wiem, że to nie odpowiada na twoje pytanie, ale Ember js wspiera coś blisko tego. Możesz zdefiniować zagnieżdżone zasoby ... które pozwalają na zagnieżdżanie szablonów w szablonach. http://emberjs.com/guides/routing/defining-your-routes/ –

Odpowiedz

20

Sposób, w jaki sobie z tym poradziłem w przeszłości, polega na osobnym zdefiniowaniu obu widoków, a następnie renderowania widoku 1, utworzenia nowego widoku 2, renderowania go i wstawienia do widoku 1. A więc:

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

To zadziałało, dzięki. – mbr1022

+1

W tym przypadku, w jaki sposób radzisz sobie ze zmianą elementu wewnętrznego? Czy zawsze renderujesz z góry na dół, czy wewnętrzny element może się jakoś zmienić? –

+0

Zmiany w elementach wewnętrznych można obsłużyć w widoku drugim, tak jak w przypadku każdej innej sytuacji.Jeśli z jakiegoś powodu widok lub model macierzysty ulegnie zmianie i wymaga ponownego renderowania html, widoki podrzędne zostaną odtworzone w tej metodzie renderowania. – RTigger

0

Typowy sposób, jak rozumiem, to postrzeganie widoków jako kompletnych obiektów, które można w sobie osadzić. Załóżmy, że masz dwa widoki: ViewA i ViewB. Poniższy kod pokazuje, w jaki sposób można dodać ViewB do 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 

Można dostać fantazyjne z jak ViewB jest zarządzany (przypisanie go do właściwości lub cokolwiek) lub przechodzić różne argumenty konstruktora w każdym przypadku ViewB.

4

Powinieneś utworzyć dla tego subviews.

Lubię sprywatyzować subviews w zamknięciu i zwrócić opinię publiczną.

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

Inną opcją, która jest przydatna, gdy trzeba to Template2 wielokrotnie w ciągu template1, powiedzieć jak <li> elementów w obrębie <ul>, ma przekazać funkcję Template2 do template1. (Z 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

bardziej suche rozwiązanie bez potrzeby jQuery append() lub dodatkowego obiektu podrzędny obejmującej podwójne zakresu jQuery jest wstępnie czyni/prekompilację ściśle stosując metodę podkreślenia i włożyć podrzędny jako ciąg, używając wewnętrznych znaczników komentarza w głównym szablonie.

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)); 
    } 
}); 

Przydaje się zwłaszcza wtedy, gdy szablon nie jest stały i zależy od właściwości bieżącego zakresu.

Zwracając uwagę, że w zakresie tego pytania należy przekazać model View2 do komponentu.

Powiązane problemy