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.