骨干采集比较器

时间:2013-11-21 17:16:08

标签: backbone.js coffeescript

我正在使用骨干和木偶,

我想对我的收藏和渲染视图进行排序。

但是发生了一些奇怪的事情。

'/ api / note / getList',它返回(并在视图初始化集合时调用)

[{"id":22,"name":"Test2","isPublic":1},{"id":11,"name":"Test1","isPublic":1},{"id":33,"name":"Test3","isPublic":1}]

这是我的收藏品,

define [
    'models/Note'
],
(Note) ->
    class NoteCollection extends Backbone.Collection

        model : Note
        url : '/api/note/getList'

        comparator : (item) =>
            console.log item.get 'id'
            return item.get 'id'

和console.log打印

22
22
11

两次打印'22'?它也没有排序。

如何对集合进行排序?

[编辑]

这是初始化集合的compisteView

define [    
    'hbs!./noteCollection_tpl'
    './noteItemView'
    'collections/NoteCollection'
],
(noteCollection_tpl, noteItemView, NoteCollection) ->
    class NoteCollectionView extends Backbone.Marionette.CompositeView
        template : noteCollection_tpl
        itemView : noteItemView
        itemViewContainer : '.noteListContainer'
        className : 'noteWrap'

        initialize : (options) ->
            @collection = new NoteCollection() 

@collection = new NoteCollection()=>我想这会自动运行。

1 个答案:

答案 0 :(得分:10)

问题是你使用绑定函数作为比较器:

comparator : (item) =>

那令人困惑的是Backbone的“比较器需要多少个参数”检查。来自fine manual

  

比较器 collection.comparator

     

[...]比较器可以定义为 sortBy (传递一个带有单个参数的函数),作为 sort (传递比较器函数,期待两个论点,[...]

如果我们查看sort,我们会看到:

if (_.isString(this.comparator) || this.comparator.length === 1) {
  this.models = this.sortBy(this.comparator, this);
} else {
  this.models.sort(_.bind(this.comparator, this));
}

因此,如果comparator是一个带有一个参数的函数(即comparator.length === 1),那么将使用sortBy并且比较器将获得一个参数;但是,如果comparator是一个不带一个参数的函数,则使用标准sort,比较器将传递两个参数。

如果您看到comparator被调用,您会看到它有两个参数。怎么会发生这种情况?如果comparator.length不是一个,就会发生这种情况。由于CoffeeScript实现comparator的方式,您的length最终会以=>为零;例如:

class C
    m1: (x) -> x
    m2: (x) => x

c = new C
console.log(c.m1.length)
console.log(c.m2.length)

会在控制台中为您提供10

演示http://jsfiddle.net/ambiguous/GAAap/

如果你看一下JavaScript:

class C
    m: (x) => x

您会看到this function is used

__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

生成=>方法。注意那里的return function() { ... }?这意味着每个=>方法都会声称length为零。恭喜,我想你已经重新发现了CoffeeScript中的一个错误。

如果您对->使用标准comparator方法:

comparator: (item) -> item.id

然后CoffeeScript不会搞砸你comparator的{​​{1}}值,你的排序将开始有意义。

演示http://jsfiddle.net/ambiguous/WXDcJ/


看起来epidemian已经报告过此错误:

  

https://github.com/jashkenas/coffee-script/pull/2872


执行摘要:不要将length用于Backbone收集比较器功能。