重新渲染视图会导致输入失去焦点

时间:2012-01-06 21:28:47

标签: backbone.js

我一遍又一遍地遇到这个问题。我有一个带输入的视图,我想在每个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}和手动更新来解决这个问题,但这会造成混乱。

1 个答案:

答案 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()});
},
});