我一遍又一遍地遇到这个问题。我有一个带输入的视图,我想在每个keyUp事件上设置和更新内容。问题是当调用set时它会触发一个更改事件,该事件会重新呈现视图,导致输入失去焦点。因此,在用户键入一个字符后,输入失去焦点,他们不能再输入。
发生这种情况的另一种情况是当用户点击输入时我想在输入周围的div中添加一个类,以便它改变颜色。这当然会导致视图重新渲染,输入失去焦点。我不能简单地为输入创建一个单独的视图,因为输入位于我想要重新渲染的div中。
这是一个简单的例子。
itemView = Backbone.View.extend({
events: {
"keyup .itemInput": "inputKeyUp"
}
initialize: function(){
this.model.view = this;
this.bind('change', this.render());
this.render();
},
render: function(){
$(this.el).html( $(ich.itemView( this.model.toJSON() )) );
return this;
},
inputKeyUp: function(e) {
this.model.set({name: $(this.view.el).find('input[type=text]').first().val()});
},
});
到目前为止,我已经通过使用{silent:true}和手动更新来解决这个问题,但这会造成混乱。
答案 0 :(得分:3)
你基本上陷入了一种无限循环的境地,你的视图与你的模型绑得太紧,而且他们互相反馈。
当用户输入浏览器文本输入时,他们已经“更新了视图”。视图已经代表了额外的文本。
因此,当您使用这些更改更新模型时,您不需要视图来更新AGAIN,因为它已经代表当前状态。
因此,在这些情况下,您确实希望使用“静默”,因为您只是将模型与UI的当前状态同步,并且不需要模型来通知视图更新。 / p>
至于经常这样做,我怀疑关键字可能过多。您可能希望在模糊或甚至是某种“保存”操作时执行此操作。
就另一个问题而言,我不确定为什么在元素中添加类会导致视图重新渲染。你只是在做像
这样的事情this.$('input[type="text"]').addClass('active')
这不应该触发模型的更改事件并导致渲染再次运行。
发表评论:
然后你需要更精细。
在渲染方面,将视图元素的单独渲染/更新分解为单独的函数。
将属性特定的更改事件(“更改:名称”)绑定到那些更细粒度的渲染函数,以便它们更新您希望更改的视图部分,但不更新文本输入。
itemView = Backbone.View.extend({
events: {
"keyup .itemInput": "inputKeyUp"
}
initialize: function(){
this.model.view = this;
this.bind('change:name', this.update_other_stuff());
this.bind('change:selected', this.add_class());
this.render();
},
update_other_stuff: function(){
this.$('.some_other_thing').html("some desired change");
return this;
},
add_class: function(){
this.$('input[type=text]').first().addClass('active');
return this;
},
render: function(){
$(this.el).html( $(ich.itemView( this.model.toJSON() )) );
return this;
},
inputKeyUp: function(e) {
this.model.set({name: $(this.view.el).find('input[type=text]').first().val()});
},
});