2013-07-19 26 views
2

我有一個Backbone Collection,我希望它以某種方式響應自己的更新(即添加,刪除,重置)。我已經在各種情況下運行到這一點,但就事論事,讓我們說,我計算哈希基於模型的IDS,快速比較集合:在添加/刪除/重置時更新Backbone Collection屬性

var HashedCollection = Backbone.Collection.extend({ 
    updateHash: function() { 
     // set a simple hash based on model id 
     this.hash = this.pluck('id').sort().join('|'); 
    } 
}); 

的問題是,什麼是正確的如何保持我的散列最新?

可能的選項:

  • 自設偵聽事件:

    this.on('add remove reset', this.updateHash, this); 
    

    這樣做的問題是,一些動作可能是無聲的,但我還是要更新哈希 - 這對於首次設置來說尤其是問題,在initialize中不會發生這種情況,因爲該集合還沒有其模型,並且初始重置事件是無聲的(relevant code)。此外,這意味着任何其他組件都可以通過傳遞{ silent: true }來混淆收集狀態。

  • 設置功能將覆蓋.add.remove.reset,和/或.set

    set: function() { 
        Backbone.Collection.prototype.set.apply(this, arguments); 
        this.updateHash(); 
    } 
    // etc 
    

    這裏最大的問題是處理單add/set電話與在reset多次調用 - reset電話add多次,它多次調用set,所以包裝set意味着我們將在重置中爲每個項目更新一次哈希。如果updateHash比上面的簡單例子更昂貴,這可能是一個真正的問題。另一個較小的問題是,我最終得到了很多重寫的函數,導致更多的半樣板代碼和更多的潛在的核心方法中的錯誤。

爲了討論的緣故,請假設:a)計算散列很昂貴,b)散列經常被引用。

有沒有更好的方法來保持收集狀態與它的模型保持一致?

+0

那你最終會做什麼? – fbynite

+0

在我自己的代碼中,我目前仍在使用一個自定義偵聽器,併爲最初的「重置」事件進行修復。但我應該把下面的答案之一標記爲正確的,因爲我認爲它們都比我現在的方法更好... – nrabinowitz

回答

1

我可能是錯的,但是,我認爲你的「最大的問題」(你的話),是一個非問題。

reset調用add一次。

// from backbone source - Backbone.Collection.reset 
reset: 
... code above ... 
this.add(models, _.extend({silent: true}, options)); // note - silent:true 
... code below ... 

add調用set一次。

// from backbone source - Backbone.Collection.add 
add: function(models, options) { 
    return this.set(models, _.defaults(options || {}, addOptions)); 
}, 

如果覆蓋set(如您已顯示)updateHash將只在復位調用一次。

set:function() { 
    Backbone.Collection.prototype.set.apply(this,arguments); 
    this.updateHash(); 
}, 

這裏是示範小提琴 - http://jsfiddle.net/5ggCd/

您還需要重寫remove

remove:function() { 
    Backbone.Collection.prototype.remove.apply(this,arguments); 
    this.updateHash(); 
}, 
+0

這是一個很好的觀點。這使得方法覆蓋選項更具吸引力。 – nrabinowitz

1

你不提供任何具體的信息,所以很難給出更詳細的答案,但總的來說,你是在倒退。直到你真正需要它,你不應該更新哈希,

getHash : function(){ 
    return this.pluck('id').sort().join('|'); 
} 

而是指this.hash你應該叫this.getHash()只要你需要它的。那麼你所有的同步問題都會消失。

如果您想在事情發生變化時進行操作,請收聽收藏事件,但您說的沒有說服我說收藏需要收聽自己。

+0

這是一個好點,但是讓我們假設a)計算哈希值是昂貴的,並且b)散列經常被引用 - 在這種情況下,您的散列按需散列方法效率低得多,然後僅在更新時進行計算。 – nrabinowitz

+0

儘管你確實發現你的方法可能是正確的,但是IFF的'.getHash'函數比較了計算散列值時的id列表和當前的id列表,並且只在必要時執行了昂貴的部分......可能是最好的選擇。 – nrabinowitz