If I have a property (a string) that is defined in a child component, how could I display that in a parent component? All the examples I see, seem to involve click events / Event Emmitter. But what if there is no event required?
CodePudding user response:
Talking from Child to Parent
There are a couple of different ways to talk from child to parent to choose from depending on the usecase:
You shouldn't get confused by the 'event'. It is just an event you create in the child as a way to talk to the parent. There doesn't need to be any user triggered event like clicks or anything.
With ViewChild
In parent.component.ts:
export class AppComponent implements AfterViewInit {
value = 'My Value';
@ViewChild(SecondChildComponent) someChild!: any
ngAfterViewInit(): void {
this.value = this.someChild.someValue
}
In child.component.ts:
someValue = 'New Value'
This value is only read 'AfterViewInit'. The parent would need some sort of event to update the value when it gets changed in the child component.
With EventEmitter Output
In child.component.ts:
@Output() someEvent = new EventEmitter
someFunction(): void {
this.someEvent.emit('Some data...')
}
In parent template:
<app-child (someEvent)="handleSomeEvent($event)"></app-child>
In parent.component.ts:
handleSomeEvent(event: any): void {
// Do something
}
Over a Router Outlet
We can use the onActivate method to get a reference to the component that gets loaded into the router-outlet.
In child.component.ts:
@Output() deleteEvent = new EventEmitter
@Output() addEvent = new EventEmitter
deleteItem(id){
this.deleteEvent.emit(id)
}
addItem(data) {
this.deleteEvent.emit(data)
}
In the parent template:
<router-outlet (activate)="onActivate($event)"></router-outlet>
In parent.component.ts:
onActivate(componentReference) {
componentReference.deleteEvent.subscribe((id) => {
// implementation
});
componentReference.addEvent.subscribe((data) => {
// implementation
})
}
With a Service
We can also use a data service bound to root to share data between unrelated components. This is also useful when a lot of other components need to access the shared data.
In service:
private sharedValue = new BehaviorSubject('')
currentSharedValue = this.sharedValue.asObservable()
changeSharedValue(newValue: string) {
this.sharedValue.next(newValue)
}
Component changing data:
constructor(
private dataService: DataService
) { }
changeSharedData(): void {
this.dataService.changeSharedValue('New Shared Data')
}
Component reading shared data:
value = 'Old Value'
subscription!: Subscription;
constructor(
private dataService: DataService
) { }
ngOnInit() {
this.subscription = this.dataService.currentSharedValue.subscribe(newValue => {
this.value = newValue
})
}
ngOnDestroy() {
this.subscription.unsubscribe()
}