Gewusst wie: erweitern/vererben Komponenten?
Ich würde gerne Erweiterungen für einige Komponenten bereits im Einsatz in Winkel-2, die zimmerreserviereung, ohne das zu umschreiben, dass Sie fast komplett, da die Basis-Komponente kann Veränderungen erfahren und wollen diese änderungen zeigten sich auch in seiner abgeleiteten Komponenten.
Erstellte ich dieses einfache Beispiel, um zu versuchen, besser zu erklären, meine Fragen:
Mit der Basis-Komponente app/base-panel.component.ts
:
import {Component, Input} from 'angular2/core';
@Component({
selector: 'base-panel',
template: '<div class="panel" [style.background-color]="color" (click)="onClick($event)">{{content}}</div>',
styles: [`
.panel{
padding: 50px;
}
`]
})
export class BasePanelComponent {
@Input() content: string;
color: string = "red";
onClick(event){
console.log("Click color: " + this.color);
}
}
Möchten Sie erstellen eine andere derivative Komponente nur verändern, zum Beispiel, eine grundlegende Komponente Verhalten im Fall von Beispiel Farbe, app/my-panel.component.ts
:
import {Component} from 'angular2/core';
import {BasePanelComponent} from './base-panel.component'
@Component({
selector: 'my-panel',
template: '<div class="panel" [style.background-color]="color" (click)="onClick($event)">{{content}}</div>',
styles: [`
.panel{
padding: 50px;
}
`]
})
export class MyPanelComponent extends BasePanelComponent{
constructor() {
super();
this.color = "blue";
}
}
Funktionsfähiges Beispiel in Plunker
Anmerkung: Offensichtlich dieses Beispiel ist einfach und gelöst werden konnten, die ansonsten keine Notwendigkeit, die Vererbung verwenden, aber es soll nur verdeutlichen das eigentliche problem.
Wie Sie sehen können, in der Umsetzung der derivativen Komponente app/my-panel.component.ts
, viel von der Umsetzung wurde wiederholt, wobei die einzelnen Teil wirklich vererbt wurde, die class
BasePanelComponent
, aber die @Component
hatte im Grunde komplett wiederholt, nicht nur die geänderten Teile, wie die selector: 'my-panel'
.
Gibt es eine Möglichkeit, um ein buchstäblich voller Vererbung einer Komponente Angular2, Erben class
definition der Markierungen/Anmerkungen, wie zum Beispiel @Component
?
Bearbeiten 1 - Feature Request
Feature request angular2 Hinzugefügt, um das Projekt auf GitHub: Erweitern/Vererben angular2 Komponenten Anmerkungen #7968
Edit 2 - Geschlossen Anfrage
Die Anfrage geschlossen wurde, aus diesem Grund, dass man sich kurz nicht wissen, wie das Zusammenführen der Dekorateur gemacht werden. Indem Sie uns mit keine Optionen. Also meiner Meinung nach ist in der zitierten Ausgabe.
- Überprüfen Sie diese Antwort stackoverflow.com/questions/36063627/... Grüße
- Ok NicolasB. Aber mein problem ist mit der Vererbung der Dekorator @ - Komponente, die ist nicht für die Vererbung von Metadaten. =/
- Leute, bitte vermeiden Sie die Verwendung von Vererbung mit Winkelgetriebe. z.B. export-Klasse PlannedFilterComponent erstreckt AbstractFilterComponent implementiert OnInit { ist sehr schlecht. Es gibt andere Wege, um code gemeinsam zu nutzen, z.B. Leistungen & kleinere Komponenten. Vererbung ist nicht der Winkel Weg. Ich bin auf eine Winkel-Projekt, wo Sie die Vererbung, und es gibt Dinge, die brechen wie Export-Komponenten Erben von der abstrakten Komponenten-Eingänge von der abstrakten Klasse.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Alternative Lösung:
Diese Antwort von Thierry Templier ist eine alternative Möglichkeit, um um das problem.
Nachdem einige Fragen mit Thierry Templier, kam ich zu dem folgenden Beispiel, dass meine Erwartungen erfüllt als alternative zur Vererbung erwähnte Einschränkung in dieser Frage:
1 - Erstellen Sie benutzerdefinierte Dekorateur:
2 - Base-Komponente mit @Component decorator:
3 - Sub-Komponente mit @CustomComponent decorator:
Plunkr mit komplette Beispiel.
Eckig 2-version 2.3 wurde gerade veröffentlicht, und es bietet eine systemeigene Komponente der Vererbung. Es sieht aus wie Sie können vererben und überschreiben, was Sie wollen, außer für-Vorlagen und-Stile. Einige Referenzen:
Neue Funktionen in Eckigen 2.3
Komponente Erbschaft in den Winkel-2
Ein Plunkr demonstrieren Komponente Vererbung
More than one component matched on this element
wenn Sie dies nicht tun.@Component()
tag. Aber, Sie können gemeinsam das .html-oder .css verweisen auf die gleiche Datei, wenn Sie wollen. Alles in allem ist es ein großes plus.Nun, dass Typoskript 2.2 unterstützt Mixins in Verbindung durch Klasse Ausdrücken wir haben einen viel besseren Weg, um auszudrücken, Mixins in Verbindung Komponenten. Beachten Sie, dass Sie können auch die Komponente der Vererbung, da eckige 2.3 (Diskussion) oder eine benutzerdefinierte Dekorateur wie bereits in anderen Antworten hier. Ich denke aber, Mixins in Verbindung haben einige Eigenschaften, die Sie besser für die Wiederverwendung von Verhalten ist in allen Komponenten:
Ich stark schlage vor, Sie Lesen das Typoskript 2.2 Ankündigung oben zu verstehen, wie Mixins in Verbindung arbeiten. Die verlinkten Diskussionen in eckigen GitHub issues liefern zusätzliche Details.
Benötigen Sie die folgenden Arten:
Dann können Sie erklären, ein Mixin wie diese
Destroyable
mixin, die hilft, die Komponenten zu behalten Abonnements an, die entsorgt werden müssten inngOnDestroy
:Zu mixin
Destroyable
in eineComponent
erklären Sie Ihre Komponente wie folgt:Beachten Sie, dass
MixinRoot
ist nur erforderlich, wenn Sie möchtenextend
eine Mixin-Komposition. Sie können ganz einfach verlängern mehrere Mixins in Verbindung z.B.A extends B(C(D))
. Dies ist die offensichtliche Linearisierung von Mixins in Verbindung, von denen ich Sprach oben, z.B. Sie effektiv verfassen inheritnace HierarchieA -> B -> C -> D
.In anderen Fällen, z.B. wenn Sie wollen, zu Komponieren, Mixins in Verbindung, die auf eine vorhandene Klasse, die Sie anwenden können Mixins etwa so:
Allerdings fand ich die erste Methode funktioniert am besten für
Components
undDirectives
wie diese müssen auch dekoriert werden mit@Component
oder@Directive
sowieso.function Destroyable<T extends Constructor<{}>>(Base = class { } as T)
. So kann ich erstellen Mixins in Verbindung mitextends Destroyable()
.export class DashboardComponent extends Destroyable(MixinRoot<SomeType>)
, mit dem generischen Zerstörbaren Klasseexport class Destroyable<T> {}
. Das Typoskript Fehler istvalue of type is not callable. Did you mean to include 'new' ?
update
Komponente-Vererbung wird unterstützt, da 2.3.0-rc.0
original
So weit, die meisten bequem für mich zu behalten-Vorlage & styles in separate
*html
&*.css
Dateien und geben Sie diese durchtemplateUrl
undstyleUrls
, so ist es leicht, wiederverwendbar.@Input()
und@Output()
Dekorateure, nicht wahr?Soweit ich weiß Komponente der Vererbung ist noch nicht umgesetzt in den Winkel-2 und ich bin mir nicht sicher, ob Sie haben Pläne, aber da die Winkel-2 ist mit Maschinenschrift (wenn Sie sich entschieden haben, diesen Weg gehen) Sie können Klassen-Vererbung-by-doing -
class MyClass extends OtherClass { ... }
. Für die Komponente der Vererbung würde ich vorschlagen, dass Sie sich mit der Winkelgeschwindigkeit 2-Projekt, indem Sie zu https://github.com/angular/angular/issues und senden eine feature-Anfrage!export class MyPanelComponent extends BasePanelComponent
), das problem ist nur, im Fall von Anmerkungen/Dekorateure werden nicht vererbt.@SubComponent()
), markiert eine Klasse als eine Unterkomponente oder mit einem extra-Feld auf der@Component
Dekorator erlaubt, einen Verweis auf einen übergeordneten Komponenten Erben.Ich weiß, das beantwortet nicht deine Frage, aber ich denke wirklich, dass Vererbung /Erweiterung von Komponenten sollte vermieden werden. Hier ist meine Argumentation:
Wenn die abstrakte Klasse erweitert, die von zwei oder mehr Komponenten enthält, die gemeinsame Logik:
verwenden Sie einen service oder sogar eine neue erstellen Typoskript Klasse, die geteilt werden können zwischen den beiden Komponenten.
Wenn die abstrakte Klasse... enthält die gemeinsam genutzte Variablen oder onClicketc Funktionen,
Dann gibt es überschneidungen zwischen der html-Code der zwei Komponenten erweitern Aussicht. Dies ist eine schlechte Praxis & die freigegebenen html-unterteilt werden muss-Komponente(s). Diese Komponente(N) (Teile) geteilt werden können zwischen den beiden Komponenten.
Fehlen mir andere Gründe dafür, dass eine abstrakte Klasse für Komponenten?
Einem Beispiel, das ich kürzlich sah, war Komponenten erweitern AutoUnsubscribe:
dieser war bas, weil die in einer großen Codebasis, infiniteSubscriptions.push() wurde nur 10 mal. Auch Import & Ausweitung der AutoUnsubscribe tatsächlich braucht mehr code als nur das hinzufügen mySubscription.unsubscribe() in der ngOnDestroy () - Methode der Komponente selbst, die erforderliche zusätzliche Logik sowieso.
Wenn jemand sucht, für eine aktualisierte Lösung, Fernando Antwort ist ziemlich perfekt. Außer, dass
ComponentMetadata
ist veraltet. MitComponent
stattdessen arbeitete für mich.Den full-Custom-Decorator
CustomDecorator.ts
- Datei sieht wie folgt aus:Importieren Sie dann in Ihrem neuen Komponente
sub-component.component.ts
- Datei, und verwenden@CustomComponent
statt@Component
wie diese:Komponenten erweitert werden kann genauso wie ein Typoskript-Klasse Vererbung, nur, dass Sie das überschreiben der Selektor mit einem neuen Namen. Alle Input() und Output() die Eigenschaften von der Übergeordneten Komponente funktioniert ganz normal
Update
@Komponente ist ein Dekorateur,
Dekorateure angewendet werden, bei der Deklaration von Klassen, nicht auf Objekten.
Grundsätzlich, Dekorateure hinzuzufügen, einige Metadaten auf das class-Objekt und kann nicht zugegriffen werden via Vererbung.
Wenn Sie erreichen wollen die Raumausstatter-Vererbung würde ich Vorschlagen, schreiben Sie eine benutzerdefinierte Dekorateur. So etwas wie unter Beispiel.
Beziehen:
https://medium.com/@ttemplier/angular2-decorators-and-class-inheritance-905921dbd1b7
Lassen uns verstehen, einige wichtige Einschränkungen & features auf Winkel-Komponente erbschaft-system.
Die Komponente erbt die Klasse Logik
Alle meta-Daten in der @Component decorator ist nicht geerbt
Komponente @Input-Eigenschaften und @Output-Eigenschaften werden vererbt
Komponenten-Lebenszyklus wird nicht vererbt
Diese Funktionen sind sehr wichtig, im Sinn haben, so lassen Sie uns untersuchen Sie jeweils unabhängig voneinander.
Die Komponente erbt die Klasse Logik
Wenn Sie Erben eine Komponente, die gesamte Logik innerhalb gleichermaßen vererbt. Es ist erwähnenswert, dass nur öffentliche member vererbt werden, als private Mitglieder nur zugänglich in der Klasse, die Sie implementiert.
Alle meta-Daten in der @Component decorator ist nicht geerbt
Die Tatsache, dass keine meta-Daten übernommen wird, scheinen mag counter-intuitive, auf den ersten, aber, wenn man darüber nachdenkt macht es wirklich Sinn. Wenn Sie Erben von einer Komponente zu sagen (Baugruppen), die Sie würde nicht wollen, dass die Wähler Baugruppen, die Sie Erben zu ersetzen, die Wähler ComponentB, das ist die Klasse, die erbt. Das gleiche kann gesagt werden für die Vorlage/templateUrl sowie Stil/styleUrls.
Komponente @Input und @Output-Eigenschaften vererbt werden
Dies ist ein weiteres feature, das ich wirklich Liebe über Komponente Erbschaft in den Winkel. In einem einfachen Satz, wenn Sie einen benutzerdefinierten @Input und @Ouput-Eigenschaft, diese Eigenschaften vererbt bekommen.
Komponente Lebenszyklus wird nicht vererbt
Dieser Teil ist nicht soo offensichtlich, vor allem für Menschen, die noch nicht ausgiebig gearbeitet mit OOP-Prinzipien. Zum Beispiel, sagen, Sie haben Baugruppen, die sich um eine Eckige vielen lifecycle-hooks wie OnInit. Wenn Sie erstellen ComponentB und Erben Baugruppen, die OnInit-Lebenszyklus von Baugruppen wird nicht ausgelöst, bis Sie explizit zu nennen, auch wenn das OnInit-lifecycle für ComponentB.
Aufruf Von Super/Base-Komponente Methoden
Um die ngOnInit () - Methode von Baugruppen Feuer, wir müssen mit dem Schlüsselwort super und rufen Sie dann die Methode, die wir brauchen, in diesem Fall ist ngOnInit. Das Schlüsselwort super verweist auf die Instanz der Komponente, die vererbt, von denen in diesem Fall werden die Baugruppen.