How To Emit An Event From Grandchildren To Grandparent In Modern Angular?
If I have multiple levels of angular components, how can I use @Output to emit an event from child to the grand parent? Grandparent:
Solution 1:
There could be 2 ways:
- Using
@output:
Grandparent
<parent (notifyGrandParent)="grandmaHandleClick($event)">
<parent>
...
grandmaHandleClick(event) {
console.log('grandma knows you clicked')
}
Parent:
<child (handleClick)="childEvent($event)">
</child>
@Output() notifyGrandParent= new EventEmitter();
childEvent(event) {
this.notifyGrandParent.emit('event')
}
Child is implemented properly in the code so it is good to go.
- Using
BehaviorSubjectviaService: With this much level of nesting, you can actually create some service likeEventService, and then createBehaviorSubjectwhich can directly be subscribed by the GrandParent. Also, to make thisservicemore component specific, you can keep this service in amodulewhich will have other 3 components (GrandParent, Parent and Child)
exportclassEventService{
private childClickedEvent = newBehaviorSubject<string>('');
emitChildEvent(msg: string){
this.childClickedEvent.next(msg)
}
childEventListner(){
returnthis.childClickedEvent.asObservable();
}
}
and then in components:
ChildComponent
exportclassChildComponent{
constructor(private evtSvc: EventService){}
onClick(){
this.evtSvc.emitChildEvent('clicked a button')
}
}
GrandParent
exportclassGrandComponent{
constructor(private evtSvc: EventService){}
ngOnInit(){
this.evtSvc.childEventListner().subscribe(info =>{
console.log(info); // here you get the message from Child component
})
}
}
Please note that, with @output event, you create a tight coupling of components and so a strong dependency (parent-child-grandchild) is created. If the component are not reusable and are only created to serve this purpose, then @output will also make sense because it'll convey the message to any new developer that they have parent-child relationship.
Creating a service to pass data also exposes the data to other components which can inject service in constructor.
So, the decision should be taken accordingly.
Solution 2:
Use rxjs/subject, it can be observer and observable in the same time.
Usage:
- Create Subject property in service:
import { Subject } from'rxjs';
exportclassAuthService {
loginAccures: Subject<boolean> = newSubject<boolean>();
}
- When event happens in child page/component use:
logout() {
this.authService.loginAccures.next(false);
}
- And subscribe to subject in parent page/component:
constructor(private authService: AuthService) {
this.authService.loginAccures.subscribe((isLoggedIn: boolean) => {
this.isLoggedIn = isLoggedIn;
})
}
Post a Comment for "How To Emit An Event From Grandchildren To Grandparent In Modern Angular?"