有趣的问题。我会在这里尝试一个关于战略模式的变体。您可以创建排序功能的哈希值,然后基于散列的选定成员上设置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