简体   繁体   中英

How to change a parent component's varibale from a child component

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.

  1. Label 1: the parent component where the variable (to be mutated) is situated.
  2. Label 2: the child component which will change parent's variable on click event.
  3. Label 3: the button inside child which will trigger the change.

在此处输入图片说明

I have checked many solutions like:

  1. Change parent component state from child component
  2. Angular access parent variable from child component
  3. Angular2: child component access parent class variable/function

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM