订阅中的变量更改后,Angular 2 View不会更新

D. *_*mon 48 typescript angular

我有一个问题,当我在我的可观察订阅中更新我的变量时,我的视图不会改变.我正在尝试显示加载微调器,同时我等待来自后端的响应,然后显示响应,但微调器不会隐藏.我的订阅看起来像这样:

this.isRequesting = "true";
this.questionService.onSubmit(form, this.questions).subscribe( (value) => {
        this._ngZone.run( () => {
             this.fileLocation = JSON.stringify(value);
             console.log(this.fileLocation);
            this.isRequesting = "false";
            console.log(this.isRequesting);
        });
    });
Run Code Online (Sandbox Code Playgroud)

我的这个组件的HTML看起来像这样:

<spinner *ngIf="isRequesting=='true'"></spinner>
Run Code Online (Sandbox Code Playgroud)

在我从后端(Springboot)获得响应后,我可以看到isRequesting在我的控制台中更改为"false",但视图仍然没有改变.微调器来自SpinKit,我修改了这个教程,让我的微调器工作.

我试过了:

  1. 教程中的方法(错误中的stopRefreshing()和observable的完整参数)
  2. ngZone强制我的视图更新.

有没有人有任何想法如何让我的观点更新或任何方式让我的微调器隐藏后我从我的后端收到回复?

Arp*_*wal 82

你在控制台上看到任何错误吗?这可能是因为在更新值后,angular没有运行更改检测.我认为你不需要ngZone.run因为它会在角度区域之外运行代码.

this.questionService.onSubmit(form, this.questions).subscribe( (value) => {
            this.fileLocation = JSON.stringify(value);
            console.log(this.fileLocation);
            this.isRequesting = "false";
            console.log(this.isRequesting);
    });
Run Code Online (Sandbox Code Playgroud)

如果由于某种原因你需要在Angular区域外运行,那么你应该告知angular通过这种方法之一运行一个变化检测周期.

  • 只需在set timeout中包装isRequesting的更新

    setTimeout( () => this.isRequesting = "false", 0);
    
    Run Code Online (Sandbox Code Playgroud)
  • 手动调用更改检测

    import {ChangeDetectorRef} from '@angular/core'
    constructor(private ref: ChangeDetectorRef){}
    
    this.questionService.onSubmit(form, this.questions).subscribe( (value)=> {
        //existing code
        console.log(this.isRequesting);
        this.ref.detectChanges();
    });
    
    Run Code Online (Sandbox Code Playgroud)

  • 嗯,这很尴尬.我没有错误并尝试过第一个解决方案,但使用`ChangeDetectionRef`的解决方案让我意识到我已将`ChangeDetectionStrategy`设置为`OnPush`.那就是问题!非常感谢你的帮助! (7认同)
  • 它是`ChangeDetectorRef`,而不是`ChangeDetectionRef` (4认同)

Flo*_*zil 16

您也可以尝试此解决方案:来自Whiletram的指南

精简版:

 import { ChangeDetectorRef } from '@angular/core';
    ...
    constructor(private cd: ChangeDetectorRef) {}
    ...
    ... .subscribe( () => {
           <yourstuff>
           this.cd.markForCheck();
        }
Run Code Online (Sandbox Code Playgroud)

你很好

背景:通过.subscribe()更改值时,angular不会通知它应该运行changedetection.所以你需要自己运行它.

  • 为什么通过`subscribe`更改值不会触发更改检测?这是我能用rxjs中的"调度程序"概念管理的东西吗? (3认同)
  • 是否有文档知道为什么通过 .subscribe() angular 更改值不会启动其更改检测? (3认同)