【问题标题】:Backbone collection comparator骨干收集比较器
【发布时间】:2013-11-21 17:16:07
【问题描述】:

我正在使用骨干和木偶,

我想对我的集合和渲染视图进行排序。

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

'/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() => 我认为这个运行会自动获取。

【问题讨论】:

  • 如果打印出集合,顺序是什么?比较器函数用于对集合进行排序,因此查看打印出来的内容并不一定会给您排序。
  • 集合初始化时,调用url。 url加载后如何hook事件?

标签: backbone.js coffeescript


【解决方案1】:

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

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 就不会搞砸你的 comparatorlength 值,你的排序就会开始有意义了。

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


看起来epidemian 已经报告了这个错误:

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


执行摘要:不要将 => 用于 Backbone 集合比较器函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-24
    • 2023-03-05
    相关资源
    最近更新 更多