This question already has answers here:
Closed 4 months ago.
I'm very new in angular 2. I have a problem to communicate between two components. When I have a layout with a parent and some child components, it's easy to set variables of the child components with the @Input annotation.
But now I have a layout of one parent component (which is mostly for the layout) and two child components:
The child component 2 have a bunch of buttons, which creates only a simple message. Now I want to display this message in child component one.
How do I resolve it? Thanks in advance
You can use @ViewChild
and @Output
to update the properties in the child component.
Alternatively you can use
@Input
in place of @ViewChild
.
The approach suggested by seidme will also work just fine. It just depends on your use case.
Example using @ViewChild
and @Output
:
https://plnkr.co/edit/r4KjoxLCFqkGzE1OkaQc?p=preview
Example using @Input
and @Output
https://plnkr.co/edit/01iRyNSvOnOG1T03xUME?p=preview
Beside the solutions using the @Input
/@Output
and a parent component as a 'bridge', a common way would also be introducing a shared service. The service needs to be provided in a parent component so the children can share single instance of the service (How do I create a singleton service in Angular 2?).
Basic example using the BehaviorSubject as a delegate:
@Injectable()
export class SharedService {
messageSource: BehaviorSubject<string> = new BehaviorSubject('');
constructor() { }
}
Child component 1:
export class ChildComponent1 {
constructor(private _sharedService: SharedService) { }
sendMessage(): void {
this._sharedService.messageSource.next('Hello from child 1!');
}
}
Child component 2:
export class ChildComponent2 {
constructor(private _sharedService: SharedService) {
this._sharedService.messageSource.subscribe((message: string) => {
console.log('Message: ', message); // => Hello from child 1!
});
}
}
See this post as well: Angular2 - Interaction between components using a service
A simple way is to set an output with @Output in your child component2 as an eventemitter and emit a event with the message passed as a data of it when a button is clicked. Then, listen to this event in your parent component and update a property that is set as an input of your child component1 when the event occurs.
The image below is an example that clearly show the mechanism
You can use template variables to reference siblings:
<child1 #child1></child1>
<child2 (someOutput)="child1.doSomething($event)"></child2>