Angular Custom Pipe OrderBy erstellen

Tutorial Angular

von Ardian Shala, 12.04.2017 - update: 12.05.2018
Eine Angular Custom Pipe ermöglicht das Definieren von weiterer Funktionalität, welche z.B.: beim Iterieren von Einträgen genutzt werden kann.
Hier wird eine injectable Custom Pipe erstellt, welche sowohl im View als auch in einer anderen Component genutzt werden kann.
Für das Sortieren wird eine einfache ".sort" Methode implementiert, die beliebig erweitert werden kann.
Zu beachten ist hier "transform", welche Zugriff auf die zu iterierende Einträge und weitere Parameter ermöglicht.
Vorraussetzung:

Downloads:

Stackblitz Demo

Update 15.05.2018

  • Beispiel erweitert/ergänzt
  • Funktionalität Custom Pipe erweitert
  • Stackblitz Demo integriert

Custom Pipe erstellen

Das Grundgerüst einer Custom Pipe besteht im Wesentlichen aus:

  • Pipe Decorator für den Namen – hier orderBy
  • Dem Ausimplementieren der transform Funktion
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ name: 'orderBy' })
export class MyOrderByPipe implements PipeTransform {
    transform(): any[] { } //hier erfolgt das Implementieren der Funktionalität
}

Sort Funktion implementieren

Zu Demonstrationszwecken wird hier eine einfache „Sortier“ Funktionalität implementiert.
Parameter sind:

  • items – Das zu iterierende Array
  • field – Der Feldname, nachdem sortiert werden soll, falls leer wird eine flache Struktur erwartet
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ name: 'orderBy' })
export class MyOrderByPipe implements PipeTransform {
  transform(items: any[], field: string): any[] {
    if (!items) return [];

    if (field) items.sort((a, b) => a[field] > b[field] ? 1 : -1);
    else items.sort((a, b) => a > b ? 1 : -1);

    return items;
  }
}

Custom Pipe im Modul integrieren

Damit die Angular Pipe im View nutzbar ist, muss sie als Declaration hinzugefügt werden.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { MyOrderByPipe } from './shared/sort.pipe';

@NgModule({
  imports: [BrowserModule, FormsModule],
  declarations: [AppComponent, MyOrderByPipe],
  bootstrap: [AppComponent]
})
export class AppModule { }

Array Struktur

Für das Verständnis wird hier von folgender Array Struktur von Objekten ausgegangen:

items = [
    { title: "third", value: "three", digit: 44 },
    { title: "second", value: "two", digit: 14 },
    { title: "first", value: "one", digit: 100 },
];

Custom Pipe im View nutzen

Anschließend lässt sich orderBy einfach nach einem Pipe-Symbol innerhalb eines ngFor benutzen.
Hier wird angegeben, dass nach title sortiert werden soll.

<ul>
    <li *ngFor="let item of items | orderBy : 'title'">
        {{item.title}} {{item.value}} {{item.digit}}
    </li>
</ul>

Custom Pipe in einer Component nutzen

Das Integrieren in einer Component setzt vorraus, dass die Custom Pipe wie ein Service als Provider hinzugefügt wird.
Anschließend kann sie in einer Component injected werden:

import { Component, OnInit } from '@angular/core';
import { MyOrderByPipe } from './shared/sort.pipe';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html'
})
export class AppComponent {
  constructor(private orderPipe: MyOrderByPipe) {
    console.log(this.orderPipe.transform(this.items, 'digit'));
  } 

  items = [
    { title: "third", value: "three", digit: 44 },
    { title: "second", value: "two", digit: 14 },
    { title: "first", value: "one", digit: 100 },
  ];

}

Custom Pipe erweitern

Mittels weiterer Parameter lässt sich die Funktionalität nun einfach erweitern.
So kann diese z.B.: um den Parameter reverse ergänzt werden, welche nach dem Sortieren das Array in umgekehrter Reihenfolge zurückliefert.

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

@Pipe({ name: 'orderBy' })
export class MyOrderByPipe implements PipeTransform {
  transform(items: any[], field: string, reverse: boolean = false): any[] {
    if (!items) return [];

    if (field) items.sort((a, b) => a[field] > b[field] ? 1 : -1);
    else items.sort((a, b) => a > b ? 1 : -1);

    if (reverse) items.reverse();

    return items;
  }
}

Fazit

Mittels Angular Custom Pipes lässt sich einfach Logik im Template integrieren.
Man sollte sie aber immer mit Vorsicht einsetzten.
Zu beachten ist hierbei die offizielle Doku von Angular: No FilterPipe

#angular #javascript #pipe #reverse #sort #typescript

Autor: Ardian Shala

Ersteller der Webseite MuchaDev. Selbstständiger IT Constultant für Frontend Technologien.