Einleitung

Bei Service-Soft ist unser Tagesgeschäft die Entwicklung von individuellen Websites und Webanwendungen. Dabei verwenden wir häufig das Framework Angular auf Grund der vielen Vorteile von Single-Page-Applications.

Um möglichst wenig Zeit und Budget von Kunden in Anspruch zu nehmen, haben wir über die Jahre viele wiederkehrende Anforderungen als Open-Source Bibliothek ausgelagert und der Allgemeinheit zur Verfügung gestellt. Eine dieser Libraries ist ngx-material-entity, die wir im Folgenden einmal vorstellen möchten.

Funktionsweise

ngx-material-entity bietet eine einfache Möglichkeit, um komplette Eingabefelder und Tabellen vollautomatisch erzeugen zu lassen, anstatt diese von Hand programmieren zu müssen. Dazu werden die Informationen direkt auf der Entität definiert, für die Eingabefelder und Tabellen erzeugt werden sollen.

Wenn man bspw. eine Adresse bestehend aus Straße, Hausnummer, PLZ und Ort hat, würde man dieser mitgeben, dass es sich jeweils um Textwerte handelt, welches Label im Eingabefeld angezeigt werden soll, ob es bestimmte Validierungen gibt (bspw. dass eine PLZ genau 5 Zeichen lang sein soll) etc.

An der Stelle wo man Eingabefelder oder gleich komplette funktionale Tabellen haben möchte benutzt man ein HTML-Element der Bibliothek und übergibt diesem eine Adresse. Alles weitere wird dann übernommen. Das Prinzip ist ähnlich wie beim Einsatz von ORMs um Klassen auf Datenbankfelder zu mappen.

Die Bibliothek ist dabei in der Lage, auch hochkomplexe Use Cases abzubilden. Dazu gehört bspw. das bedingte Anzeigen von bestimmten Eingabefeldern, definierbare Aktionen für ausgewählte Tabelleneinträge, die Unterstützung von Dateien als multipart/form-data upload und vieles mehr.

Sie möchten Unterstützung oder haben Interesse an einer Zusammenarbeit?

Vorteile

  1. Beschleunigte Entwicklung:
    ngx-material-entity bietet vorgefertigte Komponenten, die eine Menge Code-Wiederholung eliminieren. Dies beschleunigt die Entwicklung, da Entwickler sich weniger auf grundlegende UI-Komponenten konzentrieren müssen und stattdessen mehr Zeit für die Umsetzung der eigentlichen Geschäftslogik haben.
  2. Konsistente Benutzeroberfläche:
    Durch die Integration mit Angular Material ermöglicht es ngx-material-entity, eine konsistente und ansprechende Benutzeroberfläche zu erstellen. Das Framework stellt sicher, dass UI-Elemente gemäß den Material Design-Richtlinien gestaltet werden.
  3. Einfache Datenbindung:
    ngx-material-entity erleichtert die Datenbindung zwischen Benutzeroberfläche und Backend-Daten. Durch die Verwendung von Entitäten wird die Kommunikation zwischen Frontend und Backend rationalisiert, was zu einem reibungslosen Datenaustausch führt.
  4. Weniger Fehleranfälligkeit:
    Durch den Einsatz der Library wird der Code sehr viel aufgeräumter und kleiner. Dadurch wird die Wahrscheinlichkeit von Fehlern deutlich reduziert. Außerdem lässt sie sich leichter erweitern. Dies fördert die Zuverlässigkeit der Anwendung.

Beispiel/Technische Umsetzung

Einzelnes Eingabefeld

Gehen wir einmal davon aus, dass eine Anwendung an irgendeiner Stelle Addressdaten verwaltet. Eine Adresse besteht dabei immer aus einer Straße, einer Hausnummer, der PLZ sowie der Stadt.

Die Entität dafür würde dann folgendermaßen Aussehen:

import { Entity, EntityUtilities, string } from 'ngx-material-entity';

export class Address extends Entity {

    @string({
        displayName: 'Street',
        displayStyle: 'line'
    })
    street!: string;

    @string({
        displayName: 'Number',
        displayStyle: 'line'
    })
    number!: string;

    @string({
        displayName: 'Postcode',
        displayStyle: 'line',
        regex: new RegExp('^[0-9]+$'),
        maxLength: 5,
        minLength: 5
    })
    postcode!: string;

    @string({
        displayName: 'City',
        displayStyle: 'line'
    })
    city!: string;

    constructor(entity?: Address) {
        super(entity);
        EntityUtilities.new(this, entity);
    }
}
TypeScript

Wie zu sehen lassen sich auch direkt Validierungsdaten übergeben, so muss die Postleitzahl bspw. aus genau 5 Zeichen bestehen und darf nur die Ziffern 0-9 enthalten.

Um ein Eingabefeld für die Postleitzahl anzuzeigen, stellt die Bibliothek eine Komponente bereit. Dieser müssen zwei Dinge übergeben werden:
1. ein Entity-Objekt,
2. ein Key von dem Attribut, für das man ein Eingabefeld generieren lassen möchte

<ngx-mat-entity-input [entity]="entityObject" [propertyKey]="'street'">
</ngx-mat-entity-input>

<ngx-mat-entity-input [entity]="entityObject" [propertyKey]="'number'">
</ngx-mat-entity-input>

<ngx-mat-entity-input [entity]="entityObject" [propertyKey]="'postcode'">
</ngx-mat-entity-input>

<ngx-mat-entity-input [entity]="entityObject" [propertyKey]="'city'">
</ngx-mat-entity-input>
TypeScript

Das Ergebnis sieht folgendermaßen aus:

Komplette CRUD Tabelle

Die Bibliothek kann allerdings noch deutlich mehr:
Es lassen sich komplette Tabellen generieren die bspw. Adressen aus dem obigen Beispiel verwalten, sprich der Nutzer kann Adressen anlegen, editieren und Löschen und selbstdefinierte Aktionen auf Ihnen ausführen.

Und das alles mit wenigen Zeilen Code und bis ins kleinste Detail anpassbar.

Dazu wird nur noch ein Service benötigt, der die entsprechenden Routen von der Api anspricht. ngx-material-entity liefert hier direkt eine abstrakte Klasse, von der man erben kann:

import { EntityService } from 'ngx-material-entity';

@Injectable({ providedIn: 'root' })
export class AddressService extends EntityService<Address> {
    baseUrl: string = `${environment.apiUrl}/addresses`;

    constructor(http: HttpClient) {
        super(http);
    }
}
TypeScript

Der Service muss anschließend mit weiteren Konfigurationen an eine Komponente der Library gegeben werden:

import { TableData } from 'ngx-material-entity';

const tableConfig: TableData<Address> = {
    baseData: {
        title: 'Addresses',
        displayColumns: [
            {
                displayName: 'ID',
                value: (entity: Address) => entity.id
            },
            {
                displayName: 'Street',
                value: (entity: Address) => `${entity.street} ${entity.number}`
            }
        ],
        EntityClass: Address,
        EntityServiceClass: AddressService
    },
    createDialogData: {
        title: 'Create Address'
    },
    editData: {
        title: (entity: Address) => `Edit Address #${entity.id}`,
        actions: [
            {
                displayName: 'Set number to 42',
                action: (entity: Address) => entity.number = '42'
            }
        ]
    }
};
TypeScript

In diesem Beispiel wird es im Editier-Dialog noch einen Dropdown Button geben, mit dem die Hausnummer der Adresse auf 42 gesetzt wird. Wie erwähnt sind die Konfigurationsmöglichkeiten hier sehr umfangreich.

<ngx-mat-entity-table [tableData]="tableConfig"></ngx-mat-entity-table>
HTML

Dokumentation & Quellcode

Die Dokumentation sowie der Quellcode lassen sich unter https://github.com/Service-Soft/ngx-material-entity einsehen.