Ich versuche, eine übergeordnete Komponente in eine untergeordnete Komponente zu injizieren. Ich dachte, das wäre einfach. Geben Sie einfach die übergeordnete Komponente in constructor()
des Kindes ein:
constructor(private _parent:AppComponent) {} // child component constructor
Ich erhalte folgende Fehlermeldung:
AUSNAHME: Alle Parameter für ChildComponent (?) Können nicht aufgelöst werden. Stellen Sie sicher, dass alle über einen gültigen Typ oder Anmerkungen verfügen.
Was vermisse ich?
ChildComponent:
import {Component} from 'angular2/core';
import {AppComponent} from './app.component';
@Component({
selector: 'child',
template: `<p>child</p>`
})
export class ChildComponent {
constructor(private _parent:AppComponent) {}
}
AppComponent:
import {Component} from 'angular2/core';
import {ChildComponent} from './child.component';
@Component({
selector: 'my-app',
template: `{{title}} <child></child>
`,
directives: [ChildComponent]
})
export class AppComponent {
title = "Angular 2 - inject parent";
constructor() { console.clear(); }
}
Die Antwort finden Sie unter @ Kommentar von @ EricMartinez. Das Problem scheint ein Zirkelverweis zu sein, wenn A B und B A importiert.
Hier ist ein Plunker , der zwei Dateien anstelle der einen Datei in Erics Plunker verwendet.
Die einzige Änderung von meinem ursprünglichen Plunker ist die ChildComponent:
import {Component, Inject, forwardRef} from 'angular2/core';
....
constructor(@Inject(forwardRef(() => AppComponent)) private _parent:AppComponent)
Ich weiß nicht genau, ob dadurch der Zirkelverweis entfällt, da A und B sich immer noch gegenseitig importieren, aber es scheint zu funktionieren.
Siehe auch https://github.com/angular/angular/issues/3216 , wo Miško sagt:
Diese [nicht benutzerfreundliche Deklaration mit forwardRef ()] ist eine Einschränkung von JS und wie die Funktionsdeklarationen gehoben werden. Wann immer Sie eine zirkuläre Abhängigkeit haben, benötigen Sie
forwardRef
:-( Ich sehe nur ein Abwesendes.Ich würde argumentieren, dass Sie sich nicht in einer Situation befinden sollten, in der Ihre Eltern über die Kinder Bescheid wissen müssen, und Kinder sollten über die Eltern Bescheid wissen.
@Query
sollte die meisten Anwendungsfälle berücksichtigen.Es tut mir leid, aber obwohl ich damit einverstanden bin, dass dies in einigen seltenen Fällen ein Schmerz ist, sehe ich keinen Ausweg, und daher ist dieses Problem nicht umsetzbar und wird geschlossen.
Hmm ... Der Grund, warum ich die Eltern injiziert habe, war, dass ich zwei Möglichkeiten sehe, wie ein Kind mit einem Elternteil kommunizieren kann:
Und ich versuchte herauszufinden, wann ich jeden Ansatz verwenden sollte. Miško klingt wie 2. sollte selten sein.
Update: Ich habe noch etwas darüber nachgedacht ... 1. ist besser, weil es weniger Kopplung zwischen dem Kind und dem Elternteil gibt. Mit 1. muss das Kind die öffentliche API/Schnittstelle des Elternteils nicht kennen (und sollte es wahrscheinlich nicht wissen).
In umgekehrter Richtung (z. B. verwendet das übergeordnete Element @ViewChild
(@Query
ist nun veraltet), um einen Verweis auf das untergeordnete Objekt zu erhalten, und ruft Methoden für das untergeordnete Element auf), ist die Kopplung in Ordnung, da das übergeordnete Element die untergeordnete Komponente verwendet, also benötigt die öffentliche API/Schnittstelle des untergeordneten Objekts kennen, dh die Eingabe- und Ausgabeeigenschaften und die öffentlichen Methoden.
sie könnten @Host-Dekorator einfach so verwenden:
import {Component, Host} from 'angular2/core';
....
constructor(@Host() private app: AppComponent)