概述:使用模型数据动态设置视图属性
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()
来设置属性值;不在每次调用 render()
时重复设置属性值;不需要在 DOM 元素上手动设置属性值。
请注意,如果在调用 Backbone.View.extend
或视图构造函数(如 new Backbone.View
)时设置类名,则必须使用 DOM 属性名称 className
,但如果通过 attributes
哈希/方法(如本示例)来设置它,则必须使用属性名称 class
。
自 Backbone 0.9.9 起:
声明视图时...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交互的选项是非常广泛的。有两种基本的初始场景:
您可以通过各种方式为元素生成内容(设置字面字符串,如您的示例;使用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>
<!
这个模板代表完整的视图。换句话说,模板周围不会有包装器 - 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() );
}
} );
attributes
的值,就像其他一些可以提供函数或其他类型值的 Backbone 属性一样。在这些情况下,Backbone 检查该值是否为函数,调用它并使用返回值。 - JMM