3

我在点击事件时遇到问题。排序功能被触发并为每个模型执行,但既没有触发重置事件,也没有在视图上更改集合。

我在我的收藏中定义了多个排序标准,例如:

feNoRequire.Collections.CompetitionCollection = Backbone.Collection.extend({

    model: feNoRequire.Models.CompetitionModel,
    comparator: function (property) {
        return selectedStrategy.apply(model.get(property));
    },
    strategies: {
        name: function (competition) { return competition.get("name"); }, 
        nameReverse: function (competition) { console.log(competition); return -competition.get("name"); }, 
        date: function (competition) { console.log(competition.get("event")); },
    },
    changeSort: function (sortProperty) {
        this.comparator = this.strategies[sortProperty];
    },
    initialize: function () {
        this.changeSort("name");   
    }

});

在我的视图文件中:

initialize: function(options){
        this.evnt = options.evnt;

        this.collection.on('reset', this.render, this);     
        this.evnt.bind("orderByDate", this.changeSort, this);
    },

    changeSort: function(){
        this.collection.changeSort('nameReverse')
        this.collection.sort();
    },

    render: function() {
        console.log("going for rendering")
        var renderedContent = this.template({competitions: this.collection.toJSON()});

        $(this.el).html(renderedContent);
        return this;
    }

关于如何解决这个问题的任何想法?

编辑 在下面的答案之后,现在触发了渲染,但只有在初始化时才对对象进行排序。任何后续排序都以初始顺序返回集合 - this.changeSort("name");

我的模型:

feNoRequire.Models.CompetitionModel = Backbone.Model.extend({
    initialize: function(){
        this.attributes.events = new feNoRequire.Collections.EventCollection(this.attributes.events);
    }
});
4

3 回答 3

6

来自精美手册

种类 collection.sort([options])

[...] 调用 sort 会触发"sort"集合上的事件。

所以调用sort不会触发"reset"事件(因为集合没有得到reset),它会触发一个"sort"事件。所以你想:

this.collection.on('sort', this.render, this);

以及绑定到"reset".

演示:http: //jsfiddle.net/ambiguous/34Ena/


我看到你在打电话changeSort('nameReverse'),并且排序是这样的:

nameReverse: function (competition) {
    return -competition.get("name");
}

那不会做你认为它做的事,否定一个非数字字符串会给你NaN. 这意味着您最终将尝试对NaNs 列表进行排序,所有这些都是false

NaN  < NaN
NaN  > NaN
NaN == NaN

因此对 s 列表进行排序NaN没有任何用处。如果要反转排序字符串,则必须使用两个参数比较器函数:

nameReverse: function(a, b) {
    a = a.get('name');
    b = b.get('name');
    return a < b ?  1
         : a > b ? -1
         :          0;
}
于 2013-05-04T16:24:40.887 回答
1

非常好的代码设置。我真的很喜欢你通过策略对象调用排序函数的方式。

我认为此代码的问题源于以下部分:

comparator: function (property) {
    return selectedStrategy.apply(model.get(property));
},

根据文档,比较器函数采用模型或迭代器(不是属性),也不确定 selectedStrategy 应该引用什么......这是您提供的代码之外存在的另一个函数吗?

Apply 还接受一个上下文对象作为“this”,以及一个参数数组。根据关于应用的 MDN 文档:

fun.apply(thisArg[, argsArray])

除非您的模型的属性是您想用作“this”的对象,否则我认为它无法正常工作。如果我也能看到模型定义,也许会更有意义。

编辑:在阅读了其他回复后,我意识到您正在观看重置事件而不是排序,所以我的回复可能只是对您的代码的误解,而不是问题毕竟:)

于 2013-05-04T16:35:48.020 回答
1

您可以收听集合的sort事件并执行渲染。尝试将事件绑定更改为:

this.collection.on('sort reset', this.render, this);     
于 2013-05-04T16:24:24.803 回答