有趣的問題。我會在這裏嘗試一個關於戰略模式的變體。您可以創建排序功能的哈希值,然後基於散列的選定成員上設置comparator
:
App.SomeCollection = Backbone.Collection.extend({
comparator: strategies[selectedStrategy],
strategies: {
firstName: function() { /* first name sorting implementation here */ },
lastName: function() { /* last name sorting implementation here */ },
},
selectedStrategy: "firstName"
});
然後,你可以通過更新selectedStrategy
屬性的值更改動態的排序策略。
編輯:我意識到我睡覺後:)這不會像我上面寫的那樣工作,因爲我們將對象字面值傳遞給Collection.extend
。在創建對象時,comparator
屬性將被評估一次,因此除非被迫這樣做,否則它不會隨時更改。有可能是一個更清潔的方式做到這一點,但是這證明了在飛行中切換比較功能:
var SomeCollection = Backbone.Collection.extend({
comparator: function (property) {
return selectedStrategy.apply(myModel.get(property));
},
strategies: {
firstName: function (person) { return person.get("firstName"); },
lastName: function (person) { return person.get("lastName"); },
},
changeSort: function (sortProperty) {
this.comparator = this.strategies[sortProperty];
},
initialize: function() {
this.changeSort("lastName");
console.log(this.comparator);
this.changeSort("firstName");
console.log(this.comparator);
}
});
var myCollection = new SomeCollection;
這裏有一個jsFiddle演示這一點。
我認爲,所有問題的根源在於創建對象時立即評估JavaScript對象文字的屬性,因此如果要更改它,必須覆蓋該屬性。如果您嘗試寫入某種切換到屬性本身,它將被設置爲初始值並保持在那裏。
下面是一個很好的blog post,在略有不同的上下文中討論這個問題。
謝謝。建議的實現和變體已經失敗,但我很感謝迴應:)。我想我在這裏錯過了一些非常小的東西。非常令人沮喪。我傾向於另一個我的javascript工作框架,考慮了我使用簡單的排序方式難度有多大。< – kikuchiyo 2012-03-26 04:59:44
我即將自行解決此問題。我的應用程序顯示一個表。用戶將通過單擊表格中的列名稱來對錶格內容進行排序。我正在考慮讓桌面成爲一個擁有自己的「排序」模型的區域。該模型將跟蹤當前的「sortCriteria」。點擊列名將更新sortCriteria。我將在集合中有一個比較器功能。它只會從排序模型中獲取sortCriteria。 – 2014-07-16 17:34:36
需要更新JSFiddles以使用服務器上存在的Underscore和Backbone。 cdnjs.com上的那些很好。 JSFiddle用來提供自己的,但我猜不再了。 我的初步評估有點苛刻,但我認爲'myModel'應該用傳遞給比較器的參數來替換,比較器應該是集合中的每個模型。 – 2016-03-06 19:21:04