适当的方法来dynamicsortingbackbone.js集合

我可以成功地做到这一点:

App.SomeCollection = Backbone.Collection.extend({ comparator: function( collection ){ return( collection.get( 'lastName' ) ); } }); 

如果我想拥有一个只按'lastName'sorting的集合,这是很好的。 但是我需要dynamic地完成这个sorting。 有时,我需要按“firstName”来sorting。

我彻底的失败包括:

我试着传递一个额外的variables指定variablessort() 。 这没有用。 我也试过sortBy() ,也没有工作。 我尝试将自己的函数传递给sort(),但是这也不起作用。 将用户定义的函数传递给sortBy()只是为了让结果没有each方法,从而sortBy()了新分类的骨干networking集合点。

有人可以提供一个实际的例子,通过一个variables,而不是硬编码到比较函数? 或者你有什么破解的作品? 如果没有,一个工作sortBy()调用?

有趣的问题。 我会在这里尝试一个战略模式的变种。 您可以创build一个sorting函数的散列,然后根据散列的选定成员设置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属性的值来即时更改sorting策略。

编辑:我意识到我睡觉后:)这不会像我上面写的那样工作,因为我们传递一个对象文本到Collection.extend 。 在创build对象时, comparator属性将被评估一次,因此除非强制这样做,否则它不会随时更改。 有可能是一个更干净的方法来做到这一点,但这表明切换比较器function:

 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 ,演示了这一点。

我认为所有问题的根源在于,在创build对象时,会立即评估JavaScript对象文字的属性,因此如果要更改属性,则必须覆盖该属性。 如果您尝试写入某种切换到属性本身,它将被设置为初始值并保持在那里。

这里有一个很好的博客文章 ,在稍微不同的上下文中讨论这个问题。

通过分配一个新的函数来改变比较函数,并调用sort。

 // Following example above do in the view: // Assign new comparator this.collection.comparator = function( model ) { return model.get( 'lastname' ); } // Resort collection this.collection.sort(); // Sort differently this.collection.comparator = function( model ) { return model.get( 'age' ); } this.collection.sort(); 

所以,这是我的解决scheme,实际上工作。

  App.Collection = Backbone.Collection.extend({ model:App.Model, initialize: function(){ this.sortVar = 'firstName'; }, comparator: function( collection ){ var that = this; return( collection.get( that.sortVar ) ); } }); 

然后在视图中,我必须像MICKEY MOUSE那样:

 this.collections.sortVar = 'lastVar' this.collections.sort( this.comparator ).each( function(){ // All the stuff I want to do with the sorted collection... }); 

因为乔什伯爵是唯一一个甚至试图解决问题的人,他确实带领我走向正确的方向,所以我接受了他的回答。 谢谢乔希:)

这是一个古老的问题,但我最近有类似的需求(根据用户点击事件提供的标准sorting集合),并认为我会分享我的解决scheme,以解决这个问题的其他人。 不需要硬编码的model.get('attribute')。

我基本上使用Dave Newton的方法来扩展本地JavaScript数组,并将其定制为Backbone:

 MyCollection = Backbone.Collection.extend({ // Custom sorting function. sortCollection : function(criteria) { // Set your comparator function, pass the criteria. this.comparator = this.criteriaComparator(criteria); this.sort(); }, criteriaComparator : function(criteria, overloadParam) { return function(a, b) { var aSortVal = a.get(criteria); var bSortVal = b.get(criteria); // Whatever your sorting criteria. if (aSortVal < bSortVal) { return -1; } if (aSortVal > bSortVal) { return 1; } else { return 0; } }; } }); 

请注意“overloadParam”。 根据文档 ,Backbone使用Underscore的“sortBy”(如果您的比较器函数具有单个参数),如果它具有两个参数,则使用原生JS风格的sorting。 我们需要后者,因此是“overloadParam”。

看看源代码 ,似乎有一个简单的方法来做到这一点,将比较器设置为string而不是函数。 这工作,给定Backbone.Collection mycollection:

  mycollection.comparator = key; mycollection.sort(); 

这就是我正在为我正在开发的应用程序做的事情。 在我的collections中,我有:

 comparator: function(model) { var methodName = applicationStateModel.get("comparatorMethod"), method = this[methodName]; if (typeof(method === "function")) { return method.call(null, model); } } 

现在我可以添加几个不同的方法到我的集合:fooSort(),barSort()和bazSort()。
我想foo​​Sort是默认的,所以我在我的状态模型中这样设置:

 var ApplicationState = Backbone.Model.extend({ defaults: { comparatorMethod: "fooSort" } }); 

现在我所要做的就是在我的视图中编写一个函数,根据用户点击的内容更新“comparatorMethod”的值。 我设置集合来侦听这些更改并执行sort(),并将视图设置为侦听sorting事件并执行render()。

BAZINGA !!!!