2012-07-04 3 views
6

Ho 2 modelli diversi per le viste del mio modello. Ogni volta che i modelli vengono recuperati dal database, i primi 3 modelli (n. 1, 2, 3) recuperati dal back-end avranno la vista creata utilizzando il primo modello, i successivi 4 modelli (n. 4, 5, 6, 7) userà il secondo modello, i prossimi 3 modelli (# 8, 9, 10) useranno il primo modello e così via.Alternando tra 2 diversi modelli in backbone.js

Problema: Come introdurre questo modello alternativo utilizzando backbone.js?

JS Codice

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

risposta

20

Prima di tutto, la vostra PhotoListView è avvolgente una collezione così si dovrebbe utilizzare this.collection all'interno della vista e new PhotoListView({ collection: c }) per crearlo. Vista trattano il collection option similarly to how they treat model:

costruttore/inizializzarenew View([options])

[...] Ci sono diverse opzioni speciali che, se approvata, sarà alle dirette alla vista: model, collection, el, id, className, tagName e attributi.

L'utilizzo dei nomi corretti aiuta a prevenire la confusione. Inoltre, le viste hanno già aggiunto some Underscore methods, quindi puoi dire this.collection.each(...) anziché _.each(this.collection.models, ...) o _(this.collection.models).each(...). Puoi anche utilizzare this.$el anziché $(this.el).

E ora al tuo vero problema. È possibile aggiungere due modelli per il vostro per-modello di vista:

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

e la possibilità di dirgli quale usare:

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

Poi basta specificare l'opzione group dal punto di vista collezione . Underscore di each passa l'indice di iterazione alla funzione di callback come secondo argomento in modo che solo bisogno di un po 'di matematica intero per capire quale template_number da utilizzare:

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

risposta epica è epica ... Grazie –

+0

totalmente epico. .. grazie mu! – Nyxynyx

+0

Domanda: il rendering verrà chiamato per ogni elemento e la vista verrà aggiornata. Possiamo ottimizzare questo? –