Angular 4 - Заказ труб по нескольким полям

В Angular 4 у меня есть список, как показано ниже:

[{first: 'Peter', last: 'Smith'}
{first: 'John', last: 'Smith'},
{first: 'Tony', last: 'Hornet'},
{first: 'Sarah', last: 'Hornet'}]

Мне нужен канал, который будет сортировать имена по последнему, а затем сортировать по первому. Кто-нибудь знает, как это лучше всего сделать?


person Ka Tech    schedule 01.04.2018    source источник
comment
Вы не должны использовать конвейер для сортировки в первую очередь, как явно задокументировано: angular.io/guide/pipes#appendix-no-filterpipe-or-orderbypipe   -  person JB Nizet    schedule 01.04.2018


Ответы (2)


Редактировать: после комментария @JBNizet создание канала на самом деле не является предпочтительным способом, если у вас много объектов, из-за соображений производительности. (https://angular.io/guide/pipes#appendix-no-filterpipe-or-orderbypipe)

Поэтому, если у вас много объектов, вы можете отфильтровать их в своем коде ts, а не в шаблоне.

array.sort((a: any, b: any) => {
  if (!a.last.localeCompare(b.last)) 
  {
    return a.first.localeCompare(b.first);
  }
  return a.last.localeCompare(b.last);
});

Исходный ответ

Создание пайпа действительно хорошее решение

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'sortwithName'
})
export class SortPipe implements PipeTransform {

  transform(array: any[], field: string): any[] {
    array.sort((a: any, b: any) => {
      if (!a.last.localeCompare(b.last)) 
      {
        return a.first.localeCompare(b.first);
      }
      return a.last.localeCompare(b.last);
    });
    return array;
  }

}

https://stackblitz.com/edit/angular-filter-1svqdn?file=app/sortFilterPipe.ts

person David    schedule 01.04.2018
comment
Спасибо, я использовал array.sort, чтобы следовать рекомендациям. Он работает так, как ожидалось. - person Ka Tech; 02.04.2018

Вы должны создать канал, который принимает имя в качестве параметра и вызывать его в определенном порядке.

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'sortwithName'
})
export class SortPipe implements PipeTransform {

  transform(array: any[], field: string): any[] {
    array.sort((a: any, b: any) => {
      if (a[field] < b[field]) {
        return -1;
      } else if (a[field] > b[field]) {
        return 1;
      } else {
        return 0;
      }
    });
    return array;
  }

}

и в шаблоне,

 <li *ngFor="let topic of names  | sortwithName: 'last' | sortwithName: 'first'">

ДЕМО STACKBLITZ

person Sajeetharan    schedule 01.04.2018
comment
Это просто проигнорирует первую сортировку и отсортирует только по имени. Попробуйте добавить {first: 'Vera', last: 'Man'} в список, чтобы понять, что я имею в виду. - person user184994; 01.04.2018
comment
Канал Angular не предназначен для использования в качестве orderBy. angular.io/guide/pipes#no-filter-pipe - person Gili Yaniv; 01.04.2018