2012-07-04 14 views
6

Mam 2 różne szablony dla widoków mojego modelu. Za każdym razem, gdy modele są pobierane z bazy danych, pierwsze 3 modele (nr 1, 2, 3) pobrane z zaplecza będą miały widok utworzony przy użyciu pierwszego szablonu, kolejne 4 modele (# 4, 5, 6, 7) użyje drugiego szablonu, następne 3 modele (# 8, 9, 10) użyją pierwszego szablonu i tak dalej.Przełączanie między 2 różnymi szablonami w backbone.js

Problem: wprowadzenie tego naprzemiennego szablonu przy użyciu pliku backbone.js?

kod JS

// Views 

PhotoListView = Backbone.View.extend({ 
    el: '#photo_list', 

    render: function() { 
     $(this.el).html(''); 
     _.each(this.model.models, function(photo) { 
      $(this.el).append(new PhotoListItemView({ model: photo }).render().el); 
     }, this); 
     return this; 
    } 
}); 

PhotoListItemView = Backbone.View.extend({ 
    tagNAme: 'div', 
    className: 'photo_box', 

    template: _.template($('#tpl_PhotoListView').html()), 

    initialize: function() { 
     this.model.bind('destroy', this.close, this); 
    }, 

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

    close: function() { 
     this.unbind(); 
     this.remove(); 
    } 
}); 

Odpowiedz

20

Przede wszystkim, PhotoListView jest owijanie zbiór więc należy używać this.collection wewnątrz widoku i new PhotoListView({ collection: c }) go utworzyć. Widoki traktować collection option similarly to how they treat model:

konstruktor/zainicjowaćnew View([options])

[...] Istnieje kilka specjalnych opcji, które, jeśli minął, zostaną dołączone bezpośrednio do widoku: model, collection, el, id, className, tagName i atrybuty.

Używanie właściwych nazw pomoże uniknąć nieporozumień. Również widoki mają już zmieszane some Underscore methods, więc możesz powiedzieć this.collection.each(...) zamiast _.each(this.collection.models, ...) lub _(this.collection.models).each(...). Możesz także użyć this.$el zamiast $(this.el).

A teraz do twojego prawdziwego problemu. Można dodać dwa szablony do widoku per-modelu

PhotoListItemView = Backbone.View.extend({ 
    template0: _.template($('#the-first-template-id').html()), 
    template1: _.template($('#the-other-template-id').html()), 
    //... 
}); 

i możliwością jej powiedzieć, który z nich korzystać:

initialize: function(options) { 
    this.template = this['template' + options.template_number]; 
    //... 
} 

Następnie wystarczy podać opcję widoku kolekcji group . Podkreślenia na each przechodzi indeks iteracji do funkcji wywołania zwrotnego jako drugi argument więc wystarczy trochę całkowitej matematyki, aby dowiedzieć się, które template_number używać:

this.collection.each(function(photo, i) { 
    // Grouped in threes and you're alternating between two templates. 
    var n = Math.floor(i/3) % 2; 
    var v = new PhotoListItemView({ model: photo, template_number: n }); 
    this.$el.append(v.render().el); 
}, this); 
+4

epicki odpowiedź jest epicki ... Dziękuję –

+0

całkowicie epicki. .. dzięki mu! – Nyxynyx

+0

Pytanie: render będzie wywoływany dla każdego elementu, a widok będzie odświeżany. Czy możemy to zoptymalizować? –

Powiązane problemy