Backbone.js每个属性渲染(多个小视图与每个视图多个模板)
我有一个模型和一个视图。该视图显示模型的属性,并允许用户操作这些属性。问题是当一个属性被修改时,它会重新呈现整个视图,这给我带来了很多问题 文本输入上的示例模糊事件将新输入保存到属性,从而触发渲染。这意味着,如果用户从该文本输入直接单击同一视图上的按钮,该事件将永远不会触发,因为触发的第一个事件将模糊,导致整个视图重新渲染,从而丢失按钮单击事件 我有两个想法:Backbone.js每个属性渲染(多个小视图与每个视图多个模板),backbone.js,render,backbone-views,Backbone.js,Render,Backbone Views,我有一个模型和一个视图。该视图显示模型的属性,并允许用户操作这些属性。问题是当一个属性被修改时,它会重新呈现整个视图,这给我带来了很多问题 文本输入上的示例模糊事件将新输入保存到属性,从而触发渲染。这意味着,如果用户从该文本输入直接单击同一视图上的按钮,该事件将永远不会触发,因为触发的第一个事件将模糊,导致整个视图重新渲染,从而丢失按钮单击事件 我有两个想法: 具有单个视图,其中每个属性都位于单独的模板中。然后我绑定到一个特定的属性更改事件,并在render中只更新更改属性的html。这看起来像
我似乎更喜欢2号。选项你怎么认为?最佳实践是什么?有没有更好的方法来处理这个问题?我想你可以很容易地做到这一点 退一步,想想你在哪里绑定你的事件。似乎是将它们直接绑定到每个单独的元素之上,而不是使用父委托 这里有一个例子
Backbone.View.extend({
el: $("div.parent"),
events: function() {
this.$el.on("click", "input[type=button]", function(){});
// jquery cross browser on this
this.$el.on("blur", "input[type=text]", function(){});
},
initialize: function() {
this.model.bind("change", this.render, this);
},
render: function() {
this.$el.html('<input type="text" /><input type="button" />');
}
});
Backbone.View.extend({
el:$(“部门母公司”),
事件:函数(){
这个.$el.on(“单击”,“输入[type=button]”,function(){});
//jquery跨浏览器访问此服务器
这个.el.on(“blur”,“input[type=text]”,function(){});
},
初始化:函数(){
this.model.bind(“change”,this.render,this);
},
render:function(){
此.$el.html(“”);
}
});
这是el和它的结构
<div class="parent">
<input type="text" />
<input type="button" />
</div>
因此,$el指向div.parent。我可以不断地重新加载此文件的内容。$el,只要html结构不变,我就不必担心事件会被解除绑定。另一个解决方案是,如果我真的不能进行委派,我会在再次渲染时调用events方法。就像您自己所说的,您的两个选项似乎都非常复杂。但有时额外的复杂性是一种必然的罪恶。但是,如果更新的字段相对简单(比如将值绑定到元素或输入字段),我只需更新DOM元素,而无需在其上创建额外的视图/模板抽象 假设你有一个模型:
var person = new Person({ firstName: 'John', lastName: 'Lennon', instrument:'Guitar' });
以及呈现以下模板的视图:
<div>First Name: <span class="firstName">{{firstName}}</span></div>
<div>Last Name: <span class="lastName">{{lastName}}</span></div>
<div>Instrument: <input class="instrument" value="{{instrument}}"></input></div>
这样的解决方案不能扩展到非常复杂的视图,因为您必须向DOM中添加分类元素,并在视图代码中维护它们。但对于较简单的情况,这可能非常有效
此外,如果多个较小的视图自然地划分为多个部分,那么尝试组合这些视图总是很好的。这样可以避免单独更新单个字段。有关类似问题,请参阅
var PersonView = Backbone.View.extend({
//convention: propertyName+"Changed"
//specify handler as map of selector->method or a function.
firstNameChanged: { '.firstName': 'text' },
lastNameChanged: { '.lastName': 'text' },
instrumentChanged: { '.instrument': 'val' },
otherFieldChanged: function(val) { //do something else },
initialize: function (opts) {
this.model.on('change', this.update, this);
},
//called when change event is fired
update: function(state) {
_.each(state.changed, function(val, key) {
var handler = this[key + "Changed"];
//handler specified for property?
if(handler) {
//if its a function execute it
if(_.isFunction(handler)) {
handler(val);
//if its an object assume it's a selector->method map
} else if(_.isObject(handler)) {
_.each(handler, function(prop, selector) {
this.$(selector)[prop](val);
}, this);
}
}
}, this);
}