Ember - 按多个方向的多个属性对数组进行排序

Shi*_*nko 9 javascript sorting ember.js

我需要通过多个属性对Ember模型的集合进行排序,而不需要在相同的方向/顺序上.即我需要通过属性来排序一个升序秩序,财产b下降.有没有办法实现这个目标?

更新

我尝试将sortAscending属性设置为数组,但它无法正常工作.在查看源代码后,似乎不支持开箱即用(此功能).

nev*_*fox 15

在您的ArrayController中:

sortProperties: ["propA:asc", "propB:desc"]
sortedModel: Ember.computed.sort("model", "sortProperties");
Run Code Online (Sandbox Code Playgroud)

然后sortedModel在模板的#each处理程序中引用.


Shi*_*nko 5

我决定创建一个mixin,允许按多个顺序(方向)进行排序.它将SortableMixin尝试扩展到尽可能多的向后兼容.实际上它可以作为常规使用SortableMixin.它添加的是sortAscendingProperties属性,它是排序属性名称(sortProperty数组成员)的数组,应按升序排序.如果属性在sortAscendingProperties其中,它将按升序排序,否则将按照排序sortAscending,这作为默认类型.
我打电话给mixin MultiSortableMixin虽然我认为它不是最好的名字.

(function() {

    var get = Ember.get, set = Ember.set, forEach = Ember.EnumerableUtils.forEach;

    /**
     * extends the SortableMixin by allowing sorting by multiple orders.
     *
     * sortProperties - array of strings
     * sortAscending - default sort order
     * sortAscendingProperties - properties which are listed here will be sorted in ascending order, those which are not listed - will be sorted according to sortAscending
     */
    Ember.MultiSortableMixin = Ember.Mixin.create(Ember.SortableMixin, {
        /**
         Specifies the arrangedContent's sort direction

         @property {Array} sortAscendingProperties
         */
        sortAscendingProperties: null,
        orderBy: function(item1, item2) {
            var result = 0,
                    sortProperties = get(this, 'sortProperties'),
                    sortAscending = get(this, 'sortAscending'),
                    sortAscendingProperties = get(this, 'sortAscendingProperties');

            Ember.assert("you need to define `sortProperties`", !!sortProperties);

            forEach(sortProperties, function(propertyName) {
                if (result === 0) {
                    result = Ember.compare(get(item1, propertyName), get(item2, propertyName));
                    //use default sortAscending if propertyName is not listed in sortAscendingProperties
                    var sa = (sortAscendingProperties && sortAscendingProperties.indexOf(propertyName) > -1) || sortAscending;
                    if ((result !== 0) && !sa) {
                        result = (-1) * result;
                    }
                }
            });

            return result;
        },
        //overrided to add more watched props. TODO - the contents of this method is the same as parent's - find the way to just add watched stuff
        arrangedContent: Ember.computed('content', 'sortProperties.@each', 'sortAscendingProperties.@each', 'sortAscending', function(key, value) {
            var content = get(this, 'content'),
                    isSorted = get(this, 'isSorted'),
                    sortProperties = get(this, 'sortProperties'),
                    self = this;

            if (content && isSorted) {
                content = content.slice();
                content.sort(function(item1, item2) {
                    return self.orderBy(item1, item2);
                });
                forEach(content, function(item) {
                    forEach(sortProperties, function(sortProperty) {
                        Ember.addObserver(item, sortProperty, this, 'contentItemSortPropertyDidChange');
                    }, this);
                }, this);
                return Ember.A(content);
            }

            return content;
        }),
    // unneeded in this mixin, overrided to disable functionality from SortableMixin. TODO - find a way to just remove it
        sortAscendingDidChange: Ember.observer(function() {
            //empty
        }, 'sortAscending')
    });

})();
Run Code Online (Sandbox Code Playgroud)

用法示例:

App.ThingsController = Ember.ArrayController.extend(Ember.MultiSortableMixin, {
    sortProperties: ['prop1', 'prop2', 'prop3'], 
    sortAscending: false,
    sortAscendingProperties: ['prop2', 'prop3'], 
    //your stuff
});
Run Code Online (Sandbox Code Playgroud)

在这个例子中的内容ThingsController将被分类为prop1 -按降序排列,然后通过PROP2prop3 -都是按升序排列.