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
"grandmaHandleClick($event)">
...
grandmaHandleClick(event) {
console.log(" grandma="" knows="" you="" clicked'<="" span="">)
}
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
BehaviorSubject
via Service
: With this much level of nesting, you can actually create some service like EventService
, and then create BehaviorSubject
which can directly be subscribed by the GrandParent. Also, to make this service
more component specific, you can keep this service in a module
which 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?"