简介:使用模型数据动态设置视图属性
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 valrender(); 不必在DOM元素上手动设置属性。
请注意,如果在调用时设置类Backbone.View.extend或使用视图构造函数(例如new Backbone.View),则必须使用DOM属性名称className,但是,如果通过attributeshash /方法设置它(如本例所示),则必须使用属性名称class。
从主干网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,然后呈现其内容classNameid。
如何使您的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>
<!-- .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() );
}
} );