Trasmissione dei dati a componenti figlio “router-outlet” (angolari 2)

Ho un componente genitore che va al server e recupera un object.

// parent component @Component({ selector : 'node-display', template : `  ` }) export class NodeDisplayComponent implements OnInit { node: Node; ngOnInit(): void { this.nodeService.getNode(path) .subscribe( node => { this.node = node; }, err => { console.log(err); } ); } 

E in (uno dei tanti) display di mio figlio

 export class ChildDisplay implements OnInit{ @Input() node: Node; ngOnInit(): void { console.log(this.node); } } 

Non sembra che possa semplicemente iniettare dati nel router-outlet. Sembra che ottengo l’errore nella console Web …

 Can't bind to 'node' since it isn't a known property of 'router-outlet'. 

Questo ha un po ‘senso, ma come farei quanto segue ….

 1) Grab the "node" data from the server, from within the parent component 2) Pass the data I have retrieved from the server into the child router-outlet 

Non sembra che i router funzionino allo stesso modo.

L’unico modo è utilizzare un servizio condiviso.

  

è solo non valido Il componente aggiunto dal router viene aggiunto come fratello a e non lo sostituisce.

Vedi anche https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service

 @Injectable() export class NodeService { private node:Subject = new BehaviorSubject(); get node$(){ return this.node.asObservable().filter(node => !!node); } addNode(data:Node) { this.node.next(data); } } 
 @Component({ selector : 'node-display', providers: [NodeService], template : `  ` }) export class NodeDisplayComponent implements OnInit { constructor(private nodeService:NodeService) {} node: Node; ngOnInit(): void { this.nodeService.getNode(path) .subscribe( node => { this.nodeService.addNode(node); }, err => { console.log(err); } ); } } 
 export class ChildDisplay implements OnInit{ constructor(nodeService:NodeService) { nodeService.node$.subscribe(n => this.node = n); } } 

La risposta di Günters è ottima, voglio solo evidenziare un altro modo senza usare Observables.

Qui dobbiamo però ricordare che questi oggetti sono passati per riferimento, quindi se vuoi fare un po ‘di lavoro sull’object nel bambino e non influenzare l’object genitore, ti suggerirei di usare la soluzione di Günther. Ma se non importa, o in realtà è il comportamento desiderato , suggerirei quanto segue.

 @Injectable() export class SharedService { sharedNode = { // properties }; } 

Nel tuo genitore puoi assegnare il valore:

 this.sharedService.sharedNode = this.node; 

E nei tuoi figli (E padre), inserisci il servizio condiviso nel tuo costruttore. Ricordarsi di fornire il servizio a livello di modulo provider se si desidera un servizio Singleton su tutti i componenti in quel modulo. In alternativa, è sufficiente aggiungere il servizio nell’array dei provider solo nel genitore, quindi il genitore e il figlio condivideranno la stessa istanza di servizio.

 node: Node; ngOnInit() { this.node = this.sharedService.sharedNode; } 

E come gentilmente indicato da this.sharedService.sharedNode , puoi anche avere this.sharedService.sharedNode nel modello html o in un getter:

 get sharedNode(){ return this.sharedService.sharedNode; } 

Servizio:

 import {Injectable, EventEmitter} from "@angular/core"; @Injectable() export class DataService { onGetData: EventEmitter = new EventEmitter(); getData() { this.http.post(...params).map(res => { this.onGetData.emit(res.json()); }) } 

Componente:

 import {Component} from '@angular/core'; import {DataService} from "../services/data.service"; @Component() export class MyComponent { constructor(private DataService:DataService) { this.DataService.onGetData.subscribe(res => { (from service on .emit() ) }) } //To send data to all subscribers from current component sendData() { this.DataService.onGetData.emit(--NEW DATA--); } }