Angular 5 HTML 在变量更改后不更新

Gar*_*yle 8 angular angular5

我遇到一个奇怪的问题,当角度组件变量更改时,我的 HTML 页面没有更新。按下按钮后,我会进行网络加载并开始播放音频,如下所示:

onPreviewPressed(media: Media): void {
    if (this.playing) {
        this.playing = false;
        this.source.stop();
    }

    this.loading = true;

    this.service.downloadAudio(this.gender, this.style, this.ageRange, media).subscribe(abuf => {
        this.context.decodeAudioData(abuf, buffer => {
            this.source.buffer = buffer;
            this.playing = true;
            console.info(`Playing is ${this.playing}`);
            this.source.start(0);
        }, y => {
            console.info('Error: ' + y);
        });
        this.loading = false;
    }, () => {
        this.loading = false;
    });
}
Run Code Online (Sandbox Code Playgroud)

然后在我的 HTML 上我有这个片段:

Playing is {{ playing }}
<button [hidden]="!playing" style="width: 44px; height: 44px" (click)="onStopPressed()">
    <img src="/assets/stop.png" alt="Stop">
</button>
Run Code Online (Sandbox Code Playgroud)

当我单击按钮时,音频会正确下载并开始播放,在控制台中我看到它说,Playing is true但 HTML 继续说 false,并且不显示按钮。

我认为这可能不是真正的组件而是窗口变量的问题this,但如果是这样的话,那么音频确实能够播放,因为变量source是组件的一部分。

Bon*_*ich 11

我遇到了类似的问题并通过以下方式修复了它:

#Inject ChangeDetectorRef to the constructor
 constructor(private changeDetectorRef: ChangeDetectorRef)

ngOnInit(): void {
  # get data or listen to changes
  # then 
  this.changeDetectorRef.detectChanges();
}
Run Code Online (Sandbox Code Playgroud)

请记住通过以下方式导入它:

import { ChangeDetectorRef } from '@angular/core';
Run Code Online (Sandbox Code Playgroud)


Sun*_*ngh 5

可能的原因

看起来playingAngular 中的变化检测器机制并未被捕获。

修复:你有几个选择

playing第一种是对变量使用 setter 和 getter

作为变化检测器的一部分,函数始终发挥着至关重要的作用,因此它确保变量的变化得到反映。

在 *.ts 中

get playingValue(){
    return this.playing;
}

set playingValue(playing){
    this.playing = playing;
}
Run Code Online (Sandbox Code Playgroud)

在 *.html 中

Playing is {{ playingValue }}
Run Code Online (Sandbox Code Playgroud)

第二个选项是使用 setTimeout(...)

this.service.downloadAudio(this.gender, this.style, this.ageRange, media).subscribe(abuf => {
        this.context.decodeAudioData(abuf, buffer => {
            this.source.buffer = buffer;

            setTimeout(()=>this.playing = true);  //setTimeout
            
            console.info(`Playing is ${this.playing}`);
            this.source.start(0);
        }, y => {
            console.info('Error: ' + y);
        });
        this.loading = false;
    }, () => {
        this.loading = false;
    });
Run Code Online (Sandbox Code Playgroud)