Verwendung von Schnittstelle und Modell in TypeScript / Angular2

197

Ich habe kürzlich ein Tutorial zu Angular 2 mit TypeScript gesehen, bin mir aber nicht sicher, wann ich eine Schnittstelle und wann ich ein Modell zum Speichern von Datenstrukturen verwenden soll.

Beispiel einer Schnittstelle:

export interface IProduct {
    ProductNumber: number;
    ProductName: string;
    ProductDescription: string;
}

Beispiel eines Modells:

export class Product {
    constructor(
        public ProductNumber: number,
        public ProductName: string,
        public ProductDescription: string
    ){}
}

Ich möchte JSON-Daten von einer URL laden und an die Schnittstelle / das Modell binden. Manchmal möchte ich ein einzelnes Datenobjekt, ein anderes Mal möchte ich ein Array des Objekts halten.

Welches soll ich verwenden und warum?

I_LIKE_FOO
quelle
13
Verwenden Sie eine Klasse, wenn Sie eine benutzerdefinierte Logikinitialisierung benötigen. Andernfalls verwenden Sie immer eine Schnittstelle, da diese nur zur Kompilierungszeit verfügbar ist. Eine Typoskript-Schnittstelle wird nicht zu Javascript kompiliert, da sie in Javascript nicht vorhanden ist.
Dieterg
6
Beachten Sie, dass Schnittstellen in Angular 2 NICHT mit der Abhängigkeitsinjektion funktionieren. Hier müssen Sie Klassen verwenden.
Jlang

Antworten:

137

Schnittstellen sind nur zur Kompilierungszeit. Auf diese Weise können nur Sie überprüfen, ob die erwarteten empfangenen Daten einer bestimmten Struktur folgen. Dazu können Sie Ihre Inhalte auf diese Oberfläche übertragen:

this.http.get('...')
    .map(res => <Product[]>res.json());

Siehe diese Fragen:

Sie können mit class etwas Ähnliches tun, aber die Hauptunterschiede mit class bestehen darin, dass sie zur Laufzeit vorhanden sind (Konstruktorfunktion) und Sie können darin Methoden mit der Verarbeitung definieren. In diesem Fall müssen Sie jedoch Objekte instanziieren, um sie verwenden zu können:

this.http.get('...')
    .map(res => {
      var data = res.json();
      return data.map(d => {
        return new Product(d.productNumber,
          d.productName, d.productDescription);
      });
    });
Thierry Templier
quelle
27
Vielen Dank für Ihre ausführliche Antwort. Wenn die Schnittstelle nur zur Kompilierungszeit verwendet wird, wie kann der Compiler die Struktur der JSON-Datei überprüfen, ohne den http get tatsächlich zu untersuchen? Wenn dies nicht möglich ist, was bringt es dann überhaupt, sich mit einer Schnittstelle zu beschäftigen?
I_LIKE_FOO
7
@I_LIKE_FOO Der Compiler muss den get-Aufruf nicht untersuchen. Es geht nur darum, die ihm bekannten Typen zu überprüfen und sicherzustellen, dass sie korrekt ausgerichtet sind. var data = res.json();ist wirklich var data: any = res.json();für den Compiler, so dass wir alle Typprüfungen verlieren data. Was wäre nützlicher wäre hier so etwas wie var data: ProductDto[] = res.json();mit ProductDtoeiner Schnittstelle , die Modelle der Datenstruktur in dem zurück json zu sein.
GFoley83
3
Mehr: Angular style guide says not to use interfaces.Always use classes.Siehe angle.io/guide/styleguide#style-03-03
Sampath
4
Ja, aber das Problem ist, dass sie nicht die Guru-Götter sind, die Typoskript entwickelt haben. Das wäre Microsoft und Unternehmen. Sie bevorzugen Schnittstellen und gegebenenfalls Klassen. Auch Bonuspunkte ... einer ist Laufzeit und der andere ist zur Kompilierungszeit
Tom Stickel
11
@Sampath Vielleicht wurde der Angular Style Guide aktualisiert, da ich jetzt Folgendes sehe: "Erwägen Sie die Verwendung einer Schnittstelle für Datenmodelle." Impliziert, dass für Datenmodelle die Schnittstelle der Klasse vorgezogen wird.
Mikezx6r
40

Die Schnittstelle beschreibt entweder einen Vertrag für eine Klasse oder einen neuen Typ . Es ist ein reines Typescript-Element, daher wirkt es sich nicht auf Javascript aus.

Ein Modell und nämlich eine Klasse ist eine tatsächliche JS-Funktion, mit der neue Objekte generiert werden.

Ich möchte JSON-Daten von einer URL laden und an die Schnittstelle / das Modell binden.

Entscheide dich für ein Modell, sonst ist es immer noch JSON in deinem Javascript.

pietro909
quelle
4

Wie @ThierryTemplier sagte, um Daten vom Server zu empfangen und auch Modelle zwischen Komponenten zu übertragen (um die Intellisense-Liste zu führen und Entwurfszeitfehler zu machen), ist es in Ordnung, die Schnittstelle zu verwenden, aber ich denke, für das Senden von Daten an den Server (DTOs) ist es besser, die Klasse zu verwenden Vorteile der automatischen Zuordnung von DTO vom Modell.

M_Farahmand
quelle
-22

Verwenden Sie Klasse anstelle von Schnittstelle , was ich nach all meinen Nachforschungen entdeckt habe.

Warum? Eine Klasse allein ist weniger Code als eine Klasse-plus-Schnittstelle. (Auf jeden Fall benötigen Sie möglicherweise eine Klasse für das Datenmodell.)

Warum? Eine Klasse kann als Schnittstelle fungieren (verwenden Sie Implementierungen anstelle von Erweiterungen).

Warum? Eine Schnittstellenklasse kann ein Provider-Lookup-Token in Angular Dependency Injection sein.

von Angular Style Guide

Grundsätzlich kann eine Klasse alles, was eine Schnittstelle kann. Daher muss möglicherweise nie eine Schnittstelle verwendet werden .

Sajith Mantharath
quelle
10
Im Angular Style Guide heißt es derzeit tatsächlich: „ Erwägen Sie die Verwendung einer Schnittstelle für Datenmodelle.
Alex Peters
@AlexPeters Bitte geben Sie einen authentischen Link an. Danke im Voraus
Anand Phadke
@AnandPhadke sicher, hier ist ein Wayback Machine-Link zum Angular Style Guide aus der Zeit meines obigen Kommentars.
Alex Peters