【问题标题】:Function passes only once in ngOnInit函数在 ngOnInit 中只传递一次
【发布时间】:2019-12-19 18:18:30
【问题描述】:

我开发了一项服务,允许我激活按钮并查看其在不同组件中的状态。 当我点击开始/暂停时,按钮会改变图像。

在 StackBlitz 中,代码完美运行,但是当我在我的项目中实现它时,该函数只在 ngOnInit 中传递一次并且不再加载,不再更改组件之间的按钮图像。

有没有办法实现这个但不使用ngOnInit

我使用了setinterval,按钮改变了图像,但这似乎不是最好的解决方案。

谁能帮帮我?

Stackblitz

问题---关于组件

currentState: string;
ngOnInit() {
    this.currentState = this.servicesService.getCurrentState();
}

html

<div class="container" style="margin-top: 10%">
    <div class="btn-group" dropdown>
        <button id="button-basic" dropdownToggle type="button" class="btn ">
            <img style="width: 35px;" *ngIf="currentState=='pause'" src="https://img.icons8.com/carbon-copy/100/000000/play-button-circled.png">
            <img style="width: 35px;" *ngIf="currentState=='start'" src="https://img.icons8.com/cute-clipart/64/000000/stop-squared.png">
        </button>
        <ul id="dropdown-basic" *dropdownMenu class="dropdown-menu" role="menu" aria-labelledby="button-basic">
            <li role="menuitem">
              <a class="dropdown-item" *ngIf="currentState=='pause'" routerLinkActive="active" (click)="startTimer()">Start</a>
            </li>
            <li role="menuitem">
              <a class="dropdown-item" *ngIf="currentState=='start'" routerLinkActive="active" (click)="pauseTimer()">Stop</a>
            </li>
        </ul>
        <div>
            <span>{{servicesService.fetchDisplay()}}</span>
        </div>
    </div>
</div>

组件

 startTimer() {
    this.servicesService.startTimer();
    this.currentState = this.servicesService.getCurrentState();
 }

 pauseTimer() {
    this.servicesService.pauseTimer();
    this.currentState = this.servicesService.getCurrentState();
 }

【问题讨论】:

  • ngOnInit 在组件生命周期中只运行一次。如果您不想多次运行某些内容,则需要使用 setInterval 等。如果您需要运行一次,但在视图启动后,您可以尝试 ngAfterViewInit
  • 您好!您实际上需要在不同的组件中使用状态,我不会回答您的问题,但我希望您看看 blog.angular-university.io/angular-2-redux-ngrx-rxjs 。如果您计划在多个组件中使用不同的状态,NGRX 可能是一个不错的选择 :) 如果您不了解 NGRX,您应该阅读一个博客,如果您仍想使用此服务模式,我建议您获取当前的*ngIf 中的状态如下: *ngIf="this.servicesService.getCurrentState() === 'pause'"

标签: angular typescript


【解决方案1】:

你可以将你的服务定义为公开的

constructor(public servicesService: ServicesService) { }

在你的 html 中

*ngIf="servicesService.getCurrentState()=='pause'" 

【讨论】:

  • Afaik 服务不必公开,但可以在同一个组件中使用它。
  • @lama 请你解释一下为什么?我想知道你为什么这么认为。
  • 抱歉,虽然它适用于 JIT 编译器,但不适用于 AOT。 @AshotAleqsanyan 是对的,我的错。
  • @lama 如果我正确理解你所说的话。我已经使用了很多次并使用--AOT编译项目,一切都按预期工作。
  • 如果您注入“私人”服务,它不适用于 AOT,但正如您建议的“公共”服务。只要他使用 JIT 编译器,“private”就可以工作。这就是我的意思。这是一个讨论:stackoverflow.com/a/46596546/4827723
【解决方案2】:

组件

constructor(private servicesService: ServicesService) {}

public get isPlaying() {
   return this.servicesService.getCurrentState() === 'play';
}

public get isPaused() {
   return this.servicesService.getCurrentState() === 'pause'
}

HTML

*ngIf="isPlaying" 

*ngIf="isPaused" 

【讨论】:

  • 感谢您帮助我,最好的问候!
【解决方案3】:

ngOnInit 是一个 licefycle 钩子,并且总是只运行一次。如果您想在每次值更改时执行某些操作,则需要一个不同的钩子。在你的情况下可能是ngOnChanges

每次组件绑定值更改时都会调用此函数。

有关我推荐的不同钩子的更多信息:https://angular.io/guide/lifecycle-hooks

【讨论】:

    猜你喜欢
    • 2016-10-06
    • 2018-10-23
    • 1970-01-01
    • 1970-01-01
    • 2019-06-20
    • 1970-01-01
    • 2021-11-29
    • 1970-01-01
    • 2021-02-18
    相关资源
    最近更新 更多