I'm new to Angular. I'm trying to access/mutate a variable of a parent component from the child component. I've drawn a small diagram to explain my structure.
I have checked many solutions like:
But I'm not able to solve my problem. I've created an stackblitz also. Please have a look at my code.
timeselector.component.ts
import { Component, ViewChild } from '@angular/core';
import { MonthpickerComponent } from '../monthpicker/monthpicker.component';
@Component({
...
})
export class TimeselectorComponent {
x : boolean=false;
@ViewChild('primaryMonthPicker', {static: false}) primaryMonthPicker: MonthpickerComponent;
recievedFromChild:string="Intentionally left blank";
GetOutputVal($event) {
this.recievedFromChild=$event;
}
}
monthpicker.component.ts
import { Component, EventEmitter, Output } from '@angular/core';
@Component({
...
})
export class MonthpickerComponent {
@Output() outputToParent = new EventEmitter<string>();
constructor() {}
sendToParent(string:string) {
this.outputToParent.emit(string);
}
buttonClicked() {
// some logic to access and change timeselector's x
console.log("Change handler called");
}
ngOnInit() {
}
}
My actual problem is way more complex than this. But I tried to reproduce the same. I just want to see the logic of how it is done, then I'll handle the things my way. I want to change the value of x
to true
.
An expert told me to create a service. But the project is very complex and I can't make changes to it. It's a team project. Is there any quick fix or less painful solution. Please correct me I'm completely blocked because of this. Here is the stackblitz .
Check this out:
https://stackblitz.com/edit/angular-k6fnfk?file=src%2Fapp%2Fmonthpicker%2Fmonthpicker.component.html
You have to pass x
to child component, like below:
<app-monthpicker [x]="x" (outputToParent)="GetOutputVal($event)"></app-monthpicker>
Then in your monthpicker (child) component:
@Input() x;
And to change the x
value:
sendToParent() {
let newX = this.x + 1;
this.outputToParent.emit(newX);
}
On button click(OR any event), you need to emit the value to the parent component using Output decorator.
https://angular.io/guide/component-interaction#parent-listens-for-child-event
I edited your slackblitz, as you were not emiting the output on button click, now it works fine: https://stackblitz.com/edit/angular-zhpbr8
I've already got my answer. But I tried one more approach. I thought of it by myself. Please tell me to remove this if it is wrong.
Logic : Instead of hitting the value in parent component directly or using sendToparent
and this.outputToParent.emit(string);
. I created a custom mutator function in the parent component itself which will then change the state of the variable. And I'm simply calling that method from child component.
I took help from:
Angular : calling parent component function from child component
Here's my code:
parent.component.html
<app-child (parentFun)="parentFun()"></app-child>
parent.component.ts
x : boolean=false;
...
parentFun(){
this.x=true;
}
child.component.html
<button (click)="buttonClicked()">Mutate</button>
child.component.ts
@Output("parentFun") parentFun: EventEmitter<any> = new EventEmitter();
....
buttonClicked() {
this.parentFun.emit();
}
This is also working for me. With this approach I can do a lot more other changes as well. All my unit test cases are also passing on Jasmine and Karma.
Here's is a working demo: Stackblitz
Share Data between components in Angular
Check this out, the Child to Parent: Sharing Data via Output() and EventEmitter section
使用@output 和EventEmitter 从子组件中的@angular/core 向父组件发出事件,我们可以通过从子组件触发事件来更改/修改父组件的值。
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.