Как отсортировать по дате (asc или desc) наблюдаемый в угловых компонентах - PullRequest
1 голос
/ 10 ноября 2019

Мне интересно, как отсортировать по дате данные в моем массиве в моем компоненте, у меня есть следующая структура:

Шаблон:

<div>
  <button (click)="sortByDate()">
    Sort by date
  </button>
</div>
<div *ngFor="let rally of rallies$ | async">
    <img src="{{ rally.icon }}" />
</div>

Компонент:

rallies$: Observable<Rally>;

  constructor(private ralliesService: RalliesService) {}

  ngOnInit() {
    this.getRallies();
  }

  getRallies() {
    this.rallies$ = this.ralliesService.getRallies();
  }

  sortRalliesByDate() {
    ???
  }

Дело в том, что я понимаю, как работать с массивом в компоненте после подписки на наблюдаемое, но теперь я хочу работать непосредственно в наблюдаемом и работать с асинхроннымтруба в шаблоне.

Ответы [ 3 ]

1 голос
/ 10 ноября 2019

Если вы хотите отсортировать по свойству createdAt, вы можете просто отобразить его так:

sortRalliesByDate() {
  return this.rallies$
    .pipe(
      map(rallies => rallies.sort((a, b) => a.createdAt - b.createdAt)
    );
}
0 голосов
/ 11 ноября 2019

Finnaly решается таким образом:

sortRalliesByDateDesc() {
        this.rallies$ = this.rallies$.pipe(map((rallies => rallies.sort((a, b) => new Date(b.startDate).getTime() - new Date(a.startDate).getTime()))))
}

  sortRalliesByDateAsc() {
        this.rallies$ = this.rallies$.pipe(map((rallies => rallies.sort((a, b) => new Date(a.startDate).getTime() - new Date(b.startDate).getTime()))))
}

Пример Stackblitz:

https://stackblitz.com/edit/angular-glwwvv

0 голосов
/ 10 ноября 2019

Вам необходимо взять ссылку на значение, полученное из наблюдаемого, с помощью оператора as. Затем вы можете передать его в функцию сортировки.

<ng-container *ngIf="rallies$ | async as rallies">
  <div>
    <button (click)="sortByDate(rallies)">
      Sort by date
    </button>
  </div>
  <div *ngFor="let rally of rallies">
      <img src="{{ rally.icon }}" />
  </div>
</ng-container>

и заставить функцию сортировки принимать переменную шаблона в качестве параметра.

sortByDate = rallies => rallies.sort((a, b) => a.date - b.date);

Проблема с этим решением состоит в том, что вымутирует митинги, которые испускаются митингами $ наблюдаемыми. Я использую трубу клонирования, которая клонирует испускаемое значение перед присвоением переменной шаблона.

*ngIf="rallies$ | async | clone as rallies"

Таким образом, функция сортировки не вызывает никаких побочных эффектов.

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

import { clone } from './clone';

@Pipe({
  name: 'clone'
})
export class ClonePipe implements PipeTransform {

  transform(value: any): any {
    return clone(value);
  }
}

и клонfunction

export const clone = (obj: any) =>
  Array.isArray(obj)
    ? obj.map(item => clone(item))
    : obj instanceof Date
    ? new Date(obj.getTime())
    : obj && typeof obj === 'object'
    ? Object.getOwnPropertyNames(obj).reduce((o, prop) => {
        o[prop] = clone(obj[prop]);
        return o;
      }, {})
    : obj;

Клонирование означает, что у нас не было побочных эффектов с другими компонентами, которые могут использовать данные из митингов $ observable.

...