简体   繁体   English

如何从子组件调用父 function

[英]How to invoke parent function from child component

I am trying invoke parent component from child component that nested within <router-outlet> tag.我正在尝试从嵌套在<router-outlet>标记中的子组件调用父组件。 In my case, I tried to invoke timer.start() function that start the timer which lies within parent component.就我而言,我尝试调用timer.start() function 来启动位于父组件中的计时器。

I have succefully invoked the parent's function by importing to the child, but the timer is not working.我已经通过导入孩子成功调用了父母的 function,但是计时器不起作用。 I have tried to log the flag that indicated if the timer is running or not, and it's already in true condition.我试图记录指示计时器是否正在运行的标志,并且它已经处于true状态。

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:这是 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: timer.start function 也称为另一个 function,这里是 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.我有想法通过服务更改isTicking的值,并返回 observable。 I have another case similar, and it's work.我有另一个类似的案例,它的工作。 But in timer.startTime() function also modified the properties of timer.但是在timer.startTime() function 中也修改了定时器的属性。 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. 按照上面的示例使用EventEmitter是最接近它的方法。 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. 这样,您可以在需要时让两个组件调用start函数。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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