如何从子组件调用父函数

时间:2019-01-03 02:05:07

标签: javascript angular typescript

我正在尝试从嵌套在<router-outlet>标记中的子组件中调用父组件。就我而言,我试图调用timer.start()函数来启动位于父组件内的计时器。

我已经通过导入到孩子成功地调用了父函数,但是计时器不起作用。我尝试记录表示计时器是否正在运行的标志,并且该标志已经处于true状态。

代码如下:

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();
    }
}

这是timer.start函数:

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

timer.start函数也称为另一个函数,这是timer.startTimer()函数:

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);
    }
  }

我有想法通过服务更改isTicking的值,并返回可观察值。我还有另一个类似的案例,这是可行的。但是在timer.startTime()函数中还修改了计时器的属性。我也应该为此使用服务吗?还是有其他方法?

2 个答案:

答案 0 :(得分:3)

我假设您要使用父级上下文调用父级方法。 我建议避免将组件作为服务传递,因为如果有需要共享的功能-它应该是服务。但是,如果子级需要在父级上下文中触发父级方法,则可以将其传递给子级,然后从那里调用。

// 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>

答案 1 :(得分:2)

子组件无法直接在其父组件上调用函数。按照上面的示例使用EventEmitter是最接近它的方法。但是,如果您的子组件在路由模块中被声明为子路由,则您将无法执行此操作(现在有了绑定事件发射器的方法)。

我建议将您的计时器逻辑移到可以注入这两个组件的共享服务中。这样,您可以随时根据需要调用任一组件start

如果您以单例形式提供此服务(通过仅通过模块提供一次),则可以通过isTicking标志来跟踪计时器是否正在运行。