在我的主干应用程序中,我有一个由模型支持的视图,我将模型存储在集合中。页面上有几个这样的视图,一次只能选择一个。因此,我有另一个视图,其中包含这些视图的集合。当用户单击未聚焦的视图时,视图会将模型的"聚焦"属性设置为true。模型上的集合触发了一个由视图本身处理的更改事件(向其$el添加一个聚焦类)和ViewCollection视图,该视图在集合中的所有视图中循环,并取消聚焦任何聚焦的视图(除了刚刚单击的视图)。
当我以中等速度点击时,这一切都很好。但是,当我快速单击时,我会看到模型的集合行为不一致。也就是说,当我将模型的"focused"属性设置为true时,下一次单击事件显示该模型的"Focus"属性仍然为false。
代码:
var M = Backbone.Model.extend({
defaults : {
"name" : "",
"focused" : true
}
}),
L = Backbone.Collection.extend({
model : M
}),
V = Backbone.View.extend({
events : {
"click .button" : "focus"
}
initialize: function() {
this.model.bind("change:focused", this.handleFocusChange, this)
},
focus: function() {
console.log("Focus: " + this.model.get("name") + ".focused = " + this.model.get("focused"));
if (this.model.get("focused")) {
return;
}
this.model.set({focused: true}); // triggers change event
this.model.save(this.model);
console.log("Focus: " + this.model.get("name") + ".focused = " + this.model.get("focused"));
},
unfocus: function() {
console.log("Unfocus: " + this.model.get("name") + ".focused = " + this.model.get("focused"));
if (!this.model.get("focused")) {
return;
}
this.model.set({focused: false}); // triggers change event
this.model.save(this.model);
console.log("Unfocus: " + this.model.get("name") + ".focused = " + this.model.get("focused"));
},
handleFocusChange: function(model, focused) {
if (focused) {
console.log("Handling focus change on " + this.model.get("name") + ", " + this.model.cid);
this.$('.button').addClass("focused");
} else {
console.log("Handling unfocus change on " + this.model.get("nickname") + ", " + this.model.cid);
this.$('.button').removeClass("focused");
}
}
}),
ViewCollection = Backbone.View.extend({
initialize : function(options) {
_.bindAll(this, 'initViews');
this._views = [];
this.collection.each(this.initViews);
},
initViews : function(model) {
var view = new V({
model : model
});
this._views.push(view);
view.model.bind("change:focused", this.focusChanged, this);
},
focusChanged: function(changed, focused) {
if (!focused) {
return;
}
_.each(this._views, function(view) {
if (view.model.id !== changed.id) {
view.unfocus();
}
});
}
})
以下是上面日志语句的输出:
Click
Focus: A.focused = false
Handling focus change on A, c10
Unfocus: B.focused = false
Unfocus: C.focused = false
Unfocus: D.focused = true
Handling ufocus change on D, c7
Unfocus: D.focused = false
Focus: A.focused = true <-- good!
Click
Focus: C.focused = false
Handling focus change on C, c9
Unfocus: B.focused = false
Unfocus: A.focused = false <-- bad!
Unfocus: D.focused = false
Focus: C.focused = true
如您所见,我首先单击了A,然后单击了C。更改后的事件被触发,View和Collection的行为都很正常。然而,在第二次单击时,A的"focused"属性在本应为true的情况下为false。同样,只有当我快速点击视图时才会发生这种情况。当我以正常速度点击时,我无法重现这个问题。
如有任何帮助,我们将不胜感激!
这是一个需要处理的过程,但如果我正确理解您的设置。。。。看起来来自model.save()
的ajax调用失败了。
model.save()
是异步的——它在save调用返回之前触发一个更改事件。如果保存失败,更改将被撤消。尝试以下操作之一:
- 看看Firebug、Fiddler或其他什么
- 尝试将您的日志记录函数设置为
success
或error
回调,看看是哪一个触发 - 添加等待参数(
this.model.save(this.model, {wait:true});
)并查看日志记录的变化