Kręgosłup.js: zagnieżdżanie widoków za pomocą szablonów

Czy technicznie możliwe jest zagnieżdżanie widoków, używając szablonów, coś w tym stylu:

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

Mogę umieścić wszystkie rzeczy w metodzie render, ale template daje dużo więcej miejsca na elastyczność i układ.

Próbowałem wspomnianego wariantu, ale wszystko, co otrzymuję na ekranie, to [HTMLDivElement].

Jeśli próbuję wyodrębnić tylko HTML z niego, używając HTML jQuery, otrzymuję go renderowany, ale okazuje się, że węzły DOM, które zostaną wydrukowane, różnią się od te, do których widoki zawierają odniesienie, ponieważ nie jest możliwa żadna interakcja z tymi węzłami DOM przy użyciu wystąpienia widoku. Na przykład, jeśli w widoku powiem $(this.el).hide(), nic się nie stanie.

Jaki jest właściwy sposób, jeśli w ogóle?

Author: Mrchief, 2011-08-18

5 answers

Zazwyczaj najpierw renderuję widok nadrzędny. Następnie używam metody this.$('selector'), aby znaleźć element potomny, którego mogę użyć jako El widoku potomnego.

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(); 
 30
Author: Skylar Anderson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-04 06:10:51

Przyjęta odpowiedź ma poważną wadę, którą jest fakt, że Widok dziecka będzie ponownie inicjowany za każdym razem, gdy zostanie renderowany. Oznacza to, że utracisz stan i potencjalnie będziesz musiał ponownie zainicjować skomplikowane widoki przy każdym renderowaniu.

Napisałem o tym blogu TUTAJ: http://codehustler.org/blog/rendering-nested-views-backbone-js/

Podsumowując, sugerowałbym użycie 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 musisz rozszerzać widoku szkieletu, jeśli nie chcesz, metoda renderNested może być umieszczona w dowolnym miejscu.

Za pomocą powyższego kodu możesz zainicjować Widok dziecka w metodzie inicjalizacji, a następnie po prostu renderować go po wywołaniu render ().

 12
Author: Alessandro Giannone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-24 20:55:07

Zobacz kręgosłup.Subviews mixin. Jest to minimalistyczna mieszanka stworzona do zarządzania zagnieżdżonymi widokami i nie inicjuje ponownie widoków potomnych za każdym razem, gdy rodzic jest renderowany.

 2
Author: Brave Dave,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-01 19:58:49

Nie wiem jak w samym szablonie, ale robiłem to już z tabelami i listami. W zewnętrznym szablonie wystarczy mieć stub:

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

I dla poszczególnych pozycji:

Następnie w metodzie render, Renderuj poszczególne elementy i dołącz je do elementu tbody...

 1
Author: Bryce Fischer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-19 20:11:14

Decyzja o inicjalizacji nowego obiektu za każdym razem, gdy renderujesz, wydaje mi się bardzo nieefektywna. Szczególnie to:

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

Idealnie renderowanie rodzica powinno być czymś w rodzaju

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

I tworzenie dzieci powinno nastąpić tylko przy inicjalizacji rodzica:

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

Problem polega na tym, że nie mamy selector1 i selector2 przed renderowaniem szablonu nadrzędnego. To jest miejsce, w którym utknąłem teraz:)

 -1
Author: Andrey Petrov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-24 18:32:17