在Angular中按多个字段排序

391

如何在angular中同时使用多个字段进行排序?首先按组进行排序,然后按子组进行排序 例如

$scope.divisions = [{'group':1,'sub':1}, {'group':2,'sub':10}, {'group':1,'sub':2},{'group':1,'sub':20},{'group':2,'sub':1},
    {'group':2,'sub':11}];

我想将它显示为

组:子组

1-1

1-2

1-20

2-1

2-10

2-11

<select ng-model="divs" ng-options="(d.group+' - '+d.sub) for d in divisions | orderBy:'group' | orderBy:'sub'" />
8个回答

682
请查看以下内容:
请参考此链接:http://jsfiddle.net/JSWorld/Hp4W7/32/
<div ng-repeat="division in divisions | orderBy:['group','sub']">{{division.group}}-{{division.sub}}</div>

144
orderBy:['-group','sub']жҳҜз”ЁдәҺжҢүз…§groupзҡ„еҖ’еәҸиҝӣиЎҢжҺ’еәҸзҡ„гҖӮеҗҢж—¶пјҢд№ҹдјҡжҢүз…§subиҝӣиЎҢжҺ’еәҸгҖӮ - Dmytro
1
分组字段在orderBy列表中是否具有优先级? - luchosrock
5
@luchosrock,没错,正如预期的那样。通过使用提供的 jsfiddle 进行操作可以轻松确认所提供的排序字段的优先级是从左到右的。 - Patrick Refondini
2
请注意,可选的reverseOrder参数不支持像expression参数一样的数组,但您可以省略它,并在每个数组项上提供排序顺序,以便它们分别被反转(或不反转)。例如:orderBy:['group','-sub']将按正常方式按组进行排序,然后按相反的顺序按子排序。这种方法可以得到一些复杂的组合。 - Daniel Nalbach
1
我们通过为数组项设置布尔属性来模拟我们商店中的优先级,然后将其作为第一选项使用。例如:orderBy: ['-featured', 'title'],这将导致 featured 属性为 true 的项位于顶部(按字母顺序),然后是其余的按字母顺序列出的项。 - Daniel Nalbach
显示剩余3条评论

50

21
<select ng-model="divs" ng-options="(d.group+' - '+d.sub) for d in divisions | orderBy:['group','sub']" />

使用用户数组代替多个orderBY


7

有两种方法可以使用AngularJs过滤器,一种是在HTML中使用{{}},另一种是在实际的JS文件中使用...

您可以通过以下方式解决问题:

{{ Expression | orderBy : expression : reverse}}

如果您在HTML中使用它或者使用类似下面的内容:
$filter('orderBy')(yourArray, yourExpression, reverse)

在结尾处,reverse是可选的,它接受一个布尔值,如果为true,则会为您反转数组,这是一种非常方便的方式来反转您的数组...


这里也可以看一下:https://docs.angularjs.org/api/ng/filter/orderBy - Alireza

7

在angular中,可以使用“orderBy”过滤器进行排序。

有两种方式: 1. 从视图中 2. 从控制器中

  1. 从视图中

语法:

{{array | orderBy : expression : reverse}} 

例如:

 <div ng-repeat="user in users | orderBy : ['name', 'age'] : true">{{user.name}}</div>
  1. 从控制器

语法:

$filter.orderBy(array, expression, reverse);

例如:

$scope.filteredArray = $filter.orderBy($scope.users, ['name', 'age'], true);

1
我编写了这个方便的代码片段来对一个对象的多个列/属性进行排序。每次点击一个列时,代码会将上一次点击的列存储下来,并将其添加到一个名为sortArray的数组中,该数组中包含已点击的列的字符串名称。内置的Angular“orderBy”过滤器只需读取sortArray列表并按照存储在其中的列名称顺序对列进行排序。因此,最后点击的列名称成为主要的排序过滤器,先前点击的则是优先级较低的,以此类推。反向顺序会同时影响所有列的顺序,并切换完整数组列表集的升序/降序:
<script>
    app.controller('myCtrl', function ($scope) {
        $scope.sortArray = ['name'];
        $scope.sortReverse1 = false;
        $scope.searchProperty1 = '';
        $scope.addSort = function (x) {
            if ($scope.sortArray.indexOf(x) === -1) {
                $scope.sortArray.splice(0,0,x);//add to front
            }
            else {
                $scope.sortArray.splice($scope.sortArray.indexOf(x), 1, x);//remove
                $scope.sortArray.splice(0, 0, x);//add to front again
            }
        };
        $scope.sushi = [
        { name: 'Cali Roll', fish: 'Crab', tastiness: 2 },
        { name: 'Philly', fish: 'Tuna', tastiness: 2 },
        { name: 'Tiger', fish: 'Eel', tastiness: 7 },
        { name: 'Rainbow', fish: 'Variety', tastiness: 6 },
        { name: 'Salmon', fish: 'Misc', tastiness: 2 }
        ];
    });
</script>
<table style="border: 2px solid #000;">
<thead>
    <tr>
        <td><a href="#" ng-click="addSort('name');sortReverse1=!sortReverse1">NAME<span ng-show="sortReverse1==false">&#9660;</span><span ng-show="sortReverse1==true">&#9650;</span></a></td>
        <td><a href="#" ng-click="addSort('fish');sortReverse1=!sortReverse1">FISH<span ng-show="sortReverse1==false">&#9660;</span><span ng-show="sortReverse1==true">&#9650;</span></a></td>
        <td><a href="#" ng-click="addSort('tastiness');sortReverse1=!sortReverse1">TASTINESS<span ng-show="sortReverse1==false">&#9660;</span><span ng-show="sortReverse1==true">&#9650;</span></a></td>
    </tr>
</thead>
<tbody>
    <tr ng-repeat="s in sushi | orderBy:sortArray:sortReverse1 | filter:searchProperty1">
        <td>{{ s.name }}</td>
        <td>{{ s.fish }}</td>
        <td>{{ s.tastiness }}</td>
    </tr>
</tbody>
</table>

0

创建了用于排序的管道。接受字符串和字符串数组,可以按多个值进行排序。适用于 Angular(不适用于 AngularJS)。支持字符串和数字的排序。

@Pipe({name: 'orderBy'})
export class OrderBy implements PipeTransform {
    transform(array: any[], filter: any): any[] {
        if(typeof filter === 'string') {
            return this.sortAray(array, filter)
        } else {
            for (var i = filter.length -1; i >= 0; i--) {
                array = this.sortAray(array, filter[i]);
            }

            return array;
        }
    }

    private sortAray(array, field) {
        return array.sort((a, b) => {
            if(typeof a[field] !== 'string') {
                a[field] !== b[field] ? a[field] < b[field] ? -1 : 1 : 0
            } else {
                a[field].toLowerCase() !== b[field].toLowerCase() ? a[field].toLowerCase() < b[field].toLowerCase() ? -1 : 1 : 0
            }
        });
    }
}

1
其实在我看来,目前没有人回答实际问题,因为它是关于Angular而不是AngularJS的。我的解决方案适用于从Angular 2开始。已在Angular 7.2.15上进行了测试。 - Andris
你应该考虑以下两点:a)这个问题是什么时候被提出的,b)Angular 2是什么时候首次宣布的。 - Nick
@andris,你有一个完整的端到端代码示例可以在某个地方托管吗? - rolling stone
抱歉,但不行 :( - Andris

-8

确保排序对最终用户来说不太复杂。我一直认为按组和子组进行排序有点难以理解。如果是技术终端用户,可能还好。


1
这甚至不是一个相关的“评论”。肯定不是问题的答案。 - Afshin Moazami
当你进行GUI开发时,问自己当前的方法是否最好,这样做是否有错呢?对我来说,最终用户体验是相关的。 - Jens Alenius
有很多情况需要按多个属性排序,这样可以更容易地让用户理解组织的方式。实际上你是在将事物分成不同的类别。 - Owen Johnson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接