orderBy несколько полей в Angular


382

Как сортировать, используя несколько полей одновременно в угловых? кулак по группе, а затем по подгруппе для примера

$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'" />

Ответы:


659

Пожалуйста, посмотрите это:

http://jsfiddle.net/JSWorld/Hp4W7/32/

<div ng-repeat="division in divisions | orderBy:['group','sub']">{{division.group}}-{{division.sub}}</div>

137
orderBy:['-group','sub']для сортировки groupв обратном порядке.
Дмитрий

1
Имеет ли поле группы приоритет для того, чтобы быть первым в списке OrderBy?
luchosrock

5
@luchosrock, да, как и ожидалось. Игра с предоставленным jsfiddle легко подтверждает приоритет сортировки слева направо для предоставленных полей сортировки.
Патрик Рефондини

2
Обратите внимание, что необязательный параметр reverseOrder не поддерживает массив, как это делает выражение param, но вы можете его опустить и вместо этого указать порядок сортировки для каждого элемента массива, чтобы они были обращены (или нет) по отдельности. Пример: orderBy: ['group', '-sub'] будет сортировать по группе обычным образом, затем по sub в обратном порядке. Таким способом можно получить несколько сложных комбинаций.
Даниэль Нальбах

1
Мы смоделировали приоритет в нашем магазине, присвоив элементам массива логическое свойство, а затем использовали его в качестве первого параметра. Пример: orderBy: ['-featured', 'title'], из-за которого избранные истинные элементы располагаются вверху (в алфавитном порядке), а остальные элементы отображаются в алфавитном порядке.
Даниэль Нальбах


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

Пользовательский массив вместо нескольких orderBY


5

Сортировка может быть выполнена с помощью фильтра 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);

5

Есть два способа создания фильтров AngularJs, один в HTML с использованием {{}} и один в реальных файлах JS ...

Вы можете решить свою проблему с помощью:

{{ Expression | orderBy : expression : reverse}}

если вы используете его в HTML или что-то вроде:

$filter('orderBy')(yourArray, yourExpression, reverse)

Реверс необязателен в конце, он принимает логическое значение, и если это правда, он обратит Array для вас, очень удобный способ инвертировать ваш Array ...


Также здесь, чтобы посмотреть: docs.angularjs.org/api/ng/filter/orderBy
Алиреза

0

Я написал этот удобный кусок для сортировки по нескольким столбцам / свойствам объекта. При каждом последующем щелчке по столбцу код сохраняет последний нажатый столбец и добавляет его в растущий список имен строк столбцов, по которым щелкнули, помещая их в массив с именем sortArray. Встроенный угловой фильтр «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
PS: На самом деле, на мой взгляд, никто не ответил на настоящий вопрос, потому что это было для Angular, а не для AngularJS. Мое решение работает, начиная с Angular 2. Протестировано на Angular 7.2.15
Andris

Вы должны рассмотреть: а) когда был задан этот вопрос и б) когда впервые был объявлен Angular 2.
Ник

@andris У вас есть рабочий пример кода где-нибудь в конце?
Роллинг

Извините, но нет :(
Андрис

-8

Убедитесь, что сортировка не сложна для конечного пользователя. Я всегда думал, что сортировка по группе и подгруппе немного сложна для понимания. Если это технический конечный пользователь, все может быть в порядке.


Это даже не релевантный «комментарий». Наверняка нет ответа на вопрос
Афшин Моазами

Так ли неправильно задавать себе вопрос, является ли текущий подход лучшим, когда вы занимаетесь разработкой GUI? Опыт конечного пользователя кажется мне подходящим
Йенс Алениус

Существует множество сценариев, в которых сортировка по нескольким свойствам облегчает пользователю понимание организации. По сути, вы группируете вещи по категориям.
Оуэн Джонсон
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.