2012-08-01 16 views
0

在我的骨幹應用程序中,我有一個由模型支持的View,並將模型存儲在Collection中。頁面上有幾個這樣的視圖,一次只能選擇一個視圖。因此,我有另一個視圖包含這些視圖的集合。當用戶點擊未聚焦的視圖時,視圖將模型的「聚焦」屬性設置爲true。模型集觸發視圖本身處理的變化事件(將焦點類添加到它的$ el) ViewCollection視圖,該視圖循環訪問集合中的所有視圖,並忽略它們中的任何視圖專注(除了剛剛點擊的那個)。Backbone Model.set不粘?

這一切都很好,當我點擊一箇中等速度。但是,當我點擊的速度很快時,我發現模型的行爲不一致。也就是說,當我將模型的「焦點」屬性設置爲true時,下一個點擊事件表明該模型的「聚焦」屬性仍然是錯誤的。

代碼:

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的「聚焦」屬性在應該爲真時爲假。再次,這隻發生在我非常快速地點擊視圖時。當我以正常速度點擊時,我無法重現此問題。

任何幫助將不勝感激!

回答

1

這是一個很多過程,但如果我理解您的設置正確....它看起來像從model.save() ajax調用失敗。

model.save()是異步的 - 它會在保存調用返回之前觸發更改事件。如果保存失敗,則更改將被撤消。嘗試一個/以下一些:

  • 看螢火蟲,提琴手,或任何會發生什麼...
  • 嘗試把你的日誌功能爲successerror回調,看看哪火災。
  • 添加等待參數(this.model.save(this.model, {wait:true});)並查看日誌記錄如何變化。
+0

好吧,我想你可能會在這裏。我完全刪除了保存電話,但無法重現此問題。但是,當我將其添加回來時,我添加了錯誤/成功處理程序,並且在問題確實返回時,所有保存回調都成功了。等待參數在這裏不合適,我不認爲。在用戶從服務器返回響應之前,用戶很可能點擊另一個視圖。因此,我需要立即設置「聚焦」屬性,以便我知道在單擊下一個視圖時忽略該視圖。 – threejeez 2012-08-01 21:23:30

+0

關於等待參數的另一件事情:在這種情況下,服務器獲得更新的速度並不重要;所有重要的是它按順序到達那裏。因此,對於這個模型,我重寫了同步函數並實現了一次發送一個請求的ajax隊列。 js代碼可能會在更改事件被觸發之前等待很長時間。 – threejeez 2012-08-01 21:32:22

+0

我關於'wait'的觀點並不是針對最終代碼---而是指向我們實際發生的事情。所以Firebug顯示ajax成功?如果您發佈「工作」小提琴,使用HTML&all ..it可能更容易看到發生了什麼。 – EBarr 2012-08-01 21:51:20