2011-08-18 15 views
17

czy to technicznie możliwe do poglądów gniazdo, przy użyciu templating, coś takiego:backbone.js: gniazdowania poglądy poprzez szablonów

<%= new PhotoCollectionView({model:new PhotoCollection(model.similarPhotos)}).render().el) %> 

mogę umieścić wszystkie rzeczy w sposobie renderowania jak również, ale daje wiele szablonów więcej miejsca na elastyczność i układ.

Próbowałem wyżej wymieniony wariant, ale wszystko, co otrzymuję w wyniku na ekranie jest [HTMLDivElement].

Jeśli próbuję wyodrębnić z niego kod HTML, używając kodu HTML jQuery, otrzymam go renderowany, ale okazuje się, że węzły DOM, które zostaną wydrukowane, różnią się od tych, do których widoki odwołują się, ponieważ żadna interakcja z tymi węzłami DOM nie jest możliwa za pomocą instancji widoku. Na przykład, jeśli w widoku mówię: $(this.el).hide(), nic się nie stanie.

Jaki jest właściwy sposób postępowania, jeśli taki istnieje?

+1

Nie jestem pewien, czy ta technika jest technicznie możliwa, ale nie polecam, ponieważ szablony powinny zawierać tylko proste instrukcje warunkowe, a nie logikę aplikacji. Logika aplikacji powinna pozostać w widokach. W ten sposób istnieje wyraźny rozdział troski, a twoja aplikacja będzie łatwiejsza w utrzymaniu. –

+0

można zagnieżdżać widoki za pomocą React.js –

Odpowiedz

30

Zwykle najpierw renderuję widok rodzica. Następnie używam metody this.$('selector'), aby znaleźć element potomny, którego mogę użyć jako el widoku podrzędnego.

Oto pełny przykład:

var ChildView = Backbone.View.extend({ 
    //.. 
}) 

var ParentView = Backbone.View.extend({ 
    template: _.template($('#parent-template').html()), 
    initialize: function() { 
    _.bindAll(this, 'render'); 
    } 
    render: function() { 
    var child_view = new ChildView({ el: this.$('#child-el') }); //This refers to ParentView. 
    return this; 
    } 
}); 

var v = new ParentView(); 
v.render(); 
+0

cóż, tak ... skończyło się na tym samym – user802232

+5

To wydaje się trochę nieefektywne. Ponownie inicjujesz widok podrzędny za każdym razem, gdy rodzic jest renderowany. –

+4

Zgadzam się z Alessandro. Oprócz tego, że jest on nieefektywny, tracisz również stan dynamiczny w widokach podrzędnych za każdym razem, gdy renderowany jest widok nadrzędny. Sprawdź [Backbone.Subviews] (https://github.com/rotundasoftware/backbone.subviews) na gotowe do użycia rozwiązanie minimalistyczne. –

1

Nie wiem o samym szablonie, ale robiłem to wcześniej z tabelami i listami. W zewnętrznej szablonu, wystarczy niedopałek:

<script type="text/template" id="table-template"> 
    <table> 
     <thead> 
      <th>Column 1</th> 
     </thead> 
     <tbody> 
     </tbody> 
    </table> 
</script> 

i dla poszczególnych elementów: <% = pole1%>

następnie w swojej metody Render, podobnie czynią poszczególne elementy i dołączyć je do elementu tbody ...

-1

Decyzja zainicjować nowy obiekt za każdym razem czynią wydaje mi się bardzo nieefektywne. Szczególnie to:

render: function() { 
    var child_view = new ChildView({ el: this.$('#child-el') }); //This refers to ParentView. 
    return this; 
    } 

Idealnie Rendering rodzica powinno być coś jak

render: function() { 
    this.$el.html(this.template()); 
    this.childView1.render(); 
    this.childView2.render(); 
} 

A stworzenie dzieciom powinno się zdarzyć tylko przy inicjalizacji dominującej:

initialize: function() { 
     this.childView1 = new ChildView1(selector1); 
     this.childView2 = new ChildView2(selector2); 
} 

Problem polega że nie mamy selektora1 i selektora2 przed renderowaniem szablonu nadrzędnego. Właśnie tam utknąłem w tej chwili :)

+1

Wydaje się, że to nie jest odpowiedź na to pytanie, chociaż zalecenie wydaje się rozsądne. Pamiętaj, aby odpowiedzieć * na pytanie *! –

12

Przyjęta odpowiedź ma poważną wadę, co oznacza, że ​​ChildView ma być ponownie inicjowany za każdym razem, gdy jest renderowany. Oznacza to, że utracisz stan i potencjalnie będziesz musiał ponownie zainicjować skomplikowane widoki każdego renderowania.

pisałem bloga na ten temat tutaj: http://codehustler.org/blog/rendering-nested-views-backbone-js/

Podsumowując jednak, chciałbym zaproponować za pomocą czegoś takiego:

var BaseView = Backbone.View.extend({ 

    // Other code here... 

    renderNested: function(view, selector) { 
     var $element = (selector instanceof $) ? selector : this.$el.find(selector); 
     view.setElement($element).render(); 
    } 
}); 

var CustomView = BaseView.extend({ 

    // Other code here... 

    render: function() { 
     this.$el.html(this.template()); 
     this.renderNested(this.nestedView, ".selector"); 
     return this; 
    } 
}); 

Nie trzeba rozszerzyć widok Backbone jeśli nie chcesz, metodę renderNested można umieścić w dowolnym miejscu.

Za pomocą powyższego kodu można teraz zainicjować funkcję ChildView w metodzie inicjalizacji, a następnie renderować ją po wywołaniu metody render().

2

Sprawdź mieszankę Backbone.Subviews. Jest to minimalistyczny mixin stworzony do zarządzania widokami zagnieżdżonymi i nie reinicjalizuje widoków potomnych za każdym razem, gdy rodzic jest renderowany.