重新渲染视图导致输入失去焦点
我一遍又一遍地遇到这个问题。我有一个带有输入的视图,我想在每个 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} 并手动更新内容来解决这个问题,但这会造成混乱。
I keep running into this problem over and over. I have a view with an input and I want to set and update things on every keyUp event. The problem is when set is called it triggers a change event which re-renders the view which causes the input to lose focus. So after the user types one character the input loses focus and they can't type anymore.
Another case where this happens is when the user clicks on an input I want to add a class to the div around the input so that it changes color. This of course causes the view to re-render and the input loses focus. I can't simply make a separate view for the input because the input is inside the div I want to re-render.
Here's a simple example.
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()});
},
});
So far I've gotten around it by using {silent:true} and updating things manually but this creates a mess.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您基本上让自己陷入了一种无限循环的情况,您将视图与模型绑定得太紧,并且它们相互反馈。
当用户在浏览器文本输入中键入内容时,他们已经在“更新视图”。该视图已经代表了额外的文本。
因此,当您使用这些更改更新模型时,您不需要再次更新视图,因为它已经代表了当前状态。
因此,在这些情况下,您确实希望使用“静默”,因为您只是将模型与 UI 的当前状态同步,并且不需要模型通知视图进行更新。
至于多久执行一次此操作,我怀疑 keyup 可能过多。您可能想要在模糊时执行此操作,甚至在某种“保存”操作中执行此操作。
至于另一个问题,我不确定为什么向元素添加类会导致视图重新渲染。您是否只是简单地执行类似的操作,
这不应触发模型的更改事件并导致渲染再次运行。
发表评论:
那么您需要更细化。
在渲染方面,将视图元素的单独渲染/更新分解为单独的函数。
将特定于属性的更改事件(“更改:名称”)绑定到那些更精细的渲染函数,以便它们更新您希望更改的视图部分,但不更新文本输入。
You're basically getting yourself into a sort of infinite loop situation where you're binding your view too tightly to your model, and they're feeding back into each other.
When a user types into a browser text intput, they're already "updating the view". The view already represents the extra text.
So, when you update the model with those changes, you don't need the view to update AGAIN, as it already represents the current state.
So, in these cases, you really do want to use "silent", as you're just syncing the model with the current state of the UI, and don't need the model to inform the view to update.
As to how often to do this, I'm suspecting on keyup is probably excessive. You may want to do it on blur or, even, on some sort of "save" action.
As far as the other issue, I'm not sure why adding a class to an element would cause the view to re-render. Are you simply doing something like
This shouldn't trigger your model's change event and cause render to run again.
Post comment:
You need to get more granular then.
In terms of rendering, break the individual rendering/updating of elements of the view into separate functions.
Bind property-specific change events ("change:name") to those more granular rendering functions so that they update the part of the view that you wish to change, but do not update the text input.