我一遍又一遍地遇到这个问题.我有一个带输入的视图,我想在每个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()});
},
});
Run Code Online (Sandbox Code Playgroud)
到目前为止,我已经通过使用{silent:true}并手动更新内容来解决它,但这会造成混乱.
您基本上让自己陷入了一种无限循环的情况,您将视图与模型绑定得太紧,并且它们相互反馈。
当用户在浏览器文本输入中键入内容时,他们已经在“更新视图”。该视图已经代表了额外的文本。
因此,当您使用这些更改更新模型时,您不需要再次更新视图,因为它已经代表了当前状态。
因此,在这些情况下,您确实希望使用“静默”,因为您只是将模型与 UI 的当前状态同步,并且不需要模型通知视图进行更新。
至于多久执行一次此操作,我怀疑 keyup 可能过多。您可能想要在模糊时执行此操作,甚至在某种“保存”操作中执行此操作。
至于另一个问题,我不确定为什么向元素添加类会导致视图重新渲染。你只是在做类似的事情吗
this.$('input[type="text"]').addClass('active')
Run Code Online (Sandbox Code Playgroud)
这不应触发模型的更改事件并导致渲染再次运行。
发表评论:
那么你需要变得更细化。
在渲染方面,将视图元素的单独渲染/更新分解为单独的函数。
将特定于属性的更改事件(“更改:名称”)绑定到那些更精细的渲染函数,以便它们更新您希望更改的视图部分,但不更新文本输入。
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()});
},
});
Run Code Online (Sandbox Code Playgroud)