angular - parametros - ¿Cómo inyecté un componente principal en un componente secundario?
pasar datos entre componentes angular 5 (1)
Intento inyectar un componente padre en un componente secundario. Pensé que esto sería sencillo: simplemente especifica / inserta el componente padre en el constructor()
del niño constructor()
:
constructor(private _parent:AppComponent) {} // child component constructor
Obtuve el siguiente error:
EXCEPCIÓN: No se pueden resolver todos los parámetros para ChildComponent (?). Asegúrese de que todos tengan un tipo válido o anotaciones.
¿Qué me estoy perdiendo?
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(); }
}
Ver el comment @ EricMartinez para la respuesta. El problema parece ser una referencia circular cuando A importa B y B importan A.
Aquí hay un plunker que usa dos archivos en lugar del único archivo que está en plnkr .
El único cambio de mi plunker original está en ChildComponent:
import {Component, Inject, forwardRef} from ''angular2/core'';
....
constructor(@Inject(forwardRef(() => AppComponent)) private _parent:AppComponent)
No estoy seguro si esto elimina la referencia circular, ya que A y B aún se están importando, pero parece funcionar.
Ver también https://github.com/angular/angular/issues/3216 , donde Miško declara:
Esta [declaración no fácil de usar que utiliza forwardRef ()] es una limitación de JS y cómo se levantan las declaraciones de funciones. Cada vez que tenga una dependencia circular necesitará
forwardRef
:-( Simplemente no veo nada a su alrededor.Yo diría que no debería estar en una situación en la que su padre necesita saber sobre los niños y los niños que necesitan saber sobre los padres.
@Query
debería encargarse de la mayoría de los casos de uso.Lo siento, pero aunque estoy de acuerdo en que esto es un dolor en algunos casos raros, no veo una salida y, por lo tanto, este problema no es procesable, se cerrará.
Mmm ... la razón por la que intenté inyectar al padre fue porque veo dos maneras en que un niño se puede comunicar con un padre:
- el hijo define las propiedades de salida y emite eventos, a lo que el padre se suscribe
- el niño inyecta al padre (por ejemplo, Pane puede inyectar pestañas) y luego puede llamar a métodos en el padre
Y estaba tratando de determinar cuándo usar cada enfoque. Miško lo hace sonar como 2. debería ser raro.
Actualización: estaba pensando en esto un poco más ... 1. es mejor porque hay menos acoplamiento entre el niño y el padre. Con 1. el niño no necesita saber (y probablemente no debería saber) la API / interfaz pública del padre.
En la dirección inversa (por ejemplo, el padre usa @ViewChild
( @Query
ahora está en desuso) para obtener una referencia al niño, luego llama a los métodos en el niño), el acoplamiento está bien, porque el padre está usando el componente hijo, por lo que necesita conocer la API / interfaz pública del niño: es decir, las propiedades de entrada y salida y los métodos públicos.