Сводка: динамически устанавливать атрибуты представления с данными модели
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"
} )
} );
В этом примере предполагается, что вы позволяете Backbone создавать за вас элемент DOM.
attributes
Метод вызывается после того, как свойства , передаваемые вид конструктора устанавливаются (в данном случае model
), что позволяет динамически устанавливать атрибуты с модельными данными , прежде чем создает Backbone el
.
В отличие от некоторых других ответов: не жестко кодирует значения атрибутов в классе представления, динамически устанавливает их из данных модели; не render()
дожидается установки attr vals; не устанавливает повторно значение attr при каждом вызове render()
; не устанавливает значения attr для элемента DOM без необходимости вручную.
Обратите внимание , что если установка класса при вызове Backbone.View.extend
или вид конструктора (например new Backbone.View
), вы должны использовать имя свойства DOM, className
, но если установить его с помощью attributes
хэш / метода (как в этом примере) , вы должны использовать имя атрибута, class
.
Начиная с Backbone 0.9.9:
При объявлении View ... el
, tagName
, id
и className
теперь могут быть определены как функции, если вы хотите их значения должны быть определены во время выполнения.
Я упоминаю об этом на тот случай, если возникнет ситуация, когда это будет полезно в качестве альтернативы использованию attributes
метода, как показано.
Использование существующего элемента
Если вы используете существующий элемент (например, переходите el
к конструктору представления) ...
var item = new View( { el : some_el } );
... тогда attributes
не будет применяться к элементу. Если желаемые атрибуты еще не установлены в элементе или вы не хотите дублировать эти данные в своем классе представления и другом месте, вы можете добавить в конструктор представления initialize
метод, который применяется attributes
к el
. Примерно так (используя jQuery.attr
):
View.prototype.initialize = function ( options ) {
this.$el.attr( _.result( this, 'attributes' ) );
};
Использование el
, рендеринг без обертки
В большинстве примеров, которые я видел, el представления служит бессмысленным элементом оболочки, внутри которого нужно вручную писать «семантический» код.
Нет никакой причины view.el
быть «бессмысленным элементом оболочки». Фактически, это часто нарушало структуру DOM. <li>
Например, если класс представления представляет элемент, он должен быть отображен как <li>
- рендеринг его как <div>
или любого другого элемента нарушит модель содержимого. Скорее всего , вы хотите сосредоточиться на правильной настройке элемента вашей точки зрения (используя свойства , как tagName
, className
и id
) , а затем делает его содержание в дальнейшем.
Варианты того, как ваши объекты представления Backbone взаимодействуют с DOM, широко открыты. Есть 2 основных начальных сценария:
Вы можете прикрепить существующий элемент DOM к представлению Backbone.
Вы можете разрешить Backbone создать новый элемент, который отключен от документа, а затем каким-то образом вставить его в документ.
Существуют различные способы создания содержимого для элемента (установите буквальную строку, как в вашем примере; используйте библиотеку шаблонов, такую как Mustache, Handlebars и т. Д.). Как вы должны использовать el
свойство представления, зависит от того, что вы делаете.
Существующий элемент
Ваш пример рендеринга предполагает, что у вас есть существующий элемент, который вы назначаете представлению, хотя вы не показываете создание экземпляров представлений. Если это так, и элемент уже находится в документе, вы можете сделать что-то вроде этого (обновить содержимое el
, но не изменять el
себя):
render : function () {
this.$el.html( "Some stuff" );
}
http://jsfiddle.net/vQMa2/1/
Созданный элемент
Допустим, у вас нет существующего элемента, и вы разрешаете Backbone сгенерировать его за вас. Вы можете сделать что-то вроде этого (но, вероятно, лучше спроектировать вещи так, чтобы ваше представление не отвечало за знание чего-либо вне себя):
render : function () {
this.$el.html( "Some stuff" );
$( "#some-container" ).append( this.el );
}
http://jsfiddle.net/vQMa2/
Шаблоны
В моем случае я использую шаблоны, например:
<div class="player" id="{{id}}">
<input name="name" value="{{name}}" />
<input name="score" value="{{score}}" />
</div>
<!-- .player -->
Шаблон представляет собой полное представление. Другими словами, вокруг шаблона не будет оболочки - div.player
это будет корневой или самый внешний элемент моего представления.
Мой класс игрока будет выглядеть примерно так (с очень упрощенным примером 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() );
}
} );