简体   繁体   中英

How to invoke parent function from child component

I am trying invoke parent component from child component that nested within <router-outlet> tag. In my case, I tried to invoke timer.start() function that start the timer which lies within parent component.

I have succefully invoked the parent's function by importing to the child, but the timer is not working. I have tried to log the flag that indicated if the timer is running or not, and it's already in true condition.

Here is the code:

import { NavbarComponent } from './../navbar/navbar.component'; /* This is the parent component */
import { Component, OnInit } from '@angular/core';

@Component({
    selector: 'app-css-inoculation-scoring',
    templateUrl: './css-inoculation-scoring.component.html',
    styleUrls: ['./css-inoculation-scoring.component.scss'],
    providers: [ NavbarComponent ]
})

export class CSSInoculationScoringComponent implements OnInit {
    constructor(private _service: DataModelService, private _navbar: NavbarComponent) {}

    ngOnInit() {
        this.vessel.getVessel();
        this._navbar.timer.start();
    }
}

And this is the timer.start function:

start: () => {
    this.timer.isTicking = true;
    this.timer.startTime();
}

The timer.start function also called another function, here is the timer.startTimer() function:

startTime: () => {
    if (this.timer.isTicking) {
      let hour = parseInt(this.timer.hour, 10);
      let minute = parseInt(this.timer.minute, 10);
      let second = parseInt(this.timer.second, 10);

      second += 1;

      if (second > 60) {
        minute += 1;
        second = 0;
      }

      if (minute > 60) {
        hour += 1;
        minute = 0;
      }

      this.timer.second = second < 10 ? `0${second}` : `${second}`;
      this.timer.minute = minute < 10 ? `0${minute}` : `${minute}`;
      this.timer.hour = hour < 10 ? `0${hour}` : `${hour}`;

      setTimeout(this.timer.startTime, 1000);
    }
  }

I have idea to change the value of isTicking through the service, and return the observable. I have another case similar, and it's work. But in timer.startTime() function also modified the properties of timer. Should i also use service for that? Or is there any other approach?

I assume that you want to call parent's method with parent's context. I would recommend to avoid passing components as services, because if there's a functionality that needs to be shared - it should be a service. But if a child needs to trigger parent's method within parent's context, then you can pass it to a child and call if from there.

// child component  
import { Component, EventEmitter, OnInit } from '@angular/core';

@Component({
  selector: 'app-css-inoculation-scoring',
  templateUrl: './css-inoculation-scoring.component.html',
  styleUrls: ['./css-inoculation-scoring.component.scss'],
})

export class CSSInoculationScoringComponent implements OnInit {
  @Output() startTimer: EventEmitter<any> = new EventEmitter();

  constructor(private _service: DataModelService)

  ngOnInit() {
    this.vessel.getVessel();
    this.startTimer.emit();
  }
}

// PARENT COMPONENT TEMPLATE
<targeting
  (startTimer)="timer.start()">
</targeting>

Theres no way a child component can invoke a function on its parent component directly. Using an EventEmitter as per the above example is the closest thing to it. But if your child component is declared as a child route in a routing module, you wont be able to do this (there now way to bind the event emitter).

I would suggest moving your timer logic into a shared service that can be injected into both components. This way you can have either component call the start functions as and when they need to.

If you provide this service as a singleton (by providing it only once via your module), you will be able to keep track of whether the timer is running via your isTicking flag.

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