Riepilogo: imposta dinamicamente gli attributi della vista con i dati del modello
http://jsfiddle.net/5wd0ma8b/
var View = Backbone.View.extend( {
attributes : function () {
return {
class : this.model.get( 'item_class' ),
id : this.model.get( 'item_id' )
};
}
} );
var item = new View( {
model : new Backbone.Model( {
item_class : "nice",
item_id : "id1"
} )
} );
Questo esempio presuppone che tu stia consentendo a Backbone di generare un elemento DOM per te.
Il attributes
metodo viene chiamato dopo che le proprietà passate al costruttore della vista sono state impostate (in questo caso, model
), consentendo di impostare dinamicamente gli attributi con i dati del modello prima della creazione di Backbone el
.
In contrasto con alcune delle altre risposte: non codifica i valori degli attributi nella classe di visualizzazione, li imposta dinamicamente dai dati del modello; non aspetta render()
di impostare attr vals; non imposta ripetutamente attr vals in ogni chiamata a render()
; non imposta manualmente inutilmente i valori attr sull'elemento DOM.
Si noti che se l'impostazione della classe quando si chiama Backbone.View.extend
o di un costruttore vista (ad esempio new Backbone.View
), è necessario utilizzare il nome della proprietà DOM, className
ma se l'impostazione tramite il attributes
hash / metodo (come in questo esempio) è necessario utilizzare il nome dell'attributo, class
.
A partire da Backbone 0.9.9:
Quando si dichiara una vista ... el
, tagName
, id
e className
può ora essere definito come funzioni, se si vuole i loro valori da determinare in fase di esecuzione.
Lo menziono nel caso in cui ci sia una situazione in cui sarebbe utile come alternativa all'utilizzo di un attributes
metodo come illustrato.
Utilizzando un elemento esistente
Se stai usando un elemento esistente (es. Passando el
al costruttore della vista) ...
var item = new View( { el : some_el } );
... allora attributes
non verrà applicato all'elemento. Se gli attributi desiderati non sono già impostati sull'elemento, o non si vuole duplicare che i dati nella classe di visualizzazione e un altro percorso, quindi si consiglia di aggiungere un initialize
metodo per la visualizzazione costruttore che si applica attributes
a el
. Qualcosa di simile (usando jQuery.attr
):
View.prototype.initialize = function ( options ) {
this.$el.attr( _.result( this, 'attributes' ) );
};
Utilizzo di el
, rendering, evitando il wrapper
Nella maggior parte degli esempi che ho visto, el della vista serve come un elemento wrapper senza significato all'interno del quale si deve scrivere manualmente il codice "semantico".
Non c'è motivo view.el
per cui debba essere "un elemento wrapper privo di significato". In effetti, ciò spesso romperebbe la struttura DOM. Se una classe di visualizzazione rappresenta un <li>
elemento, ad esempio, deve essere renderizzato come un <li>
- renderlo come un <div>
o qualsiasi altro elemento interromperà il modello di contenuto. È probabile che vuole mettere a fuoco su come impostare correttamente elemento del vostro vista (utilizzando le proprietà come tagName
, className
, e id
) e poi di pronunciare la contenuti da allora in poi.
Le opzioni su come far interagire gli oggetti della vista Backbone con il DOM sono completamente aperte. Esistono 2 scenari iniziali di base:
Puoi collegare un elemento DOM esistente a una vista Backbone.
È possibile consentire a Backbone di creare un nuovo elemento disconnesso dal documento, quindi inserirlo in qualche modo nel documento.
Esistono vari modi per generare il contenuto per l'elemento (impostare una stringa letterale, come nel tuo esempio; utilizzare una libreria di modelli come Moustache, Handlebars, ecc.). Il modo in cui dovresti usare la el
proprietà della vista dipende da cosa stai facendo.
Elemento esistente
Il tuo esempio di rendering suggerisce che hai un elemento esistente che stai assegnando alla vista, sebbene non mostri l'istanza delle viste. Se è così e l'elemento è già nel documento, allora potresti voler fare qualcosa di simile (aggiorna il contenuto di el
, ma non alterare el
se stesso):
render : function () {
this.$el.html( "Some stuff" );
}
http://jsfiddle.net/vQMa2/1/
Elemento generato
Diciamo che non hai un elemento esistente e permetti a Backbone di generarne uno per te. Si potrebbe voler fare qualcosa di simile (ma è probabile meglio le cose architetto in modo che la vista non è responsabile di conoscere qualsiasi cosa fuori di sé):
render : function () {
this.$el.html( "Some stuff" );
$( "#some-container" ).append( this.el );
}
http://jsfiddle.net/vQMa2/
Modelli
Nel mio caso, sto usando modelli, ad esempio:
<div class="player" id="{{id}}">
<input name="name" value="{{name}}" />
<input name="score" value="{{score}}" />
</div>
<!-- .player -->
Il modello rappresenta la vista completa. In altre parole, non ci sarà alcun wrapper attorno al modello: div.player
sarà l'elemento principale o più esterno della mia vista.
La mia classe giocatore sarà simile a questa (con un esempio molto semplificato di render()
):
Backbone.View.extend( {
tagName : 'div',
className : 'player',
attributes : function () {
return {
id : "player-" + this.model.cid
};
},
render : function {
var rendered_template = $( ... );
this.$el.empty().append( rendered_template.children() );
}
} );