【问题标题】:Angular 2 View will not update after variable change in subscribe订阅中的变量更改后,Angular 2 View 不会更新
【发布时间】:2016-07-18 20:42:44
【问题描述】:

我有一个问题,当我在可观察订阅中更新我的变量时,我的视图不会改变。我试图在等待来自后端的响应然后显示响应时显示加载微调器,但微调器不会隐藏。我的订阅如下所示:

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

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

<spinner *ngIf="isRequesting=='true'"></spinner>

从后端(Springboot)收到响应后,我可以在控制台中看到 isRequesting 更改为“false”,但视图仍然没有改变。微调器来自SpinKit,我修改了这个tutorial 以使我的微调器工作。

我试过了:

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

在我收到后端响应后,是否有人对如何更新我的视图或以任何方式让我的微调器隐藏有任何想法?

【问题讨论】:

    标签: typescript angular


    【解决方案1】:

    您在控制台上看到任何错误吗? 这可能是因为在您对值进行更新后 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);
        });
    

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

    • 只需将 isRequesting 的更新包装到设置超时中

      setTimeout( () => this.isRequesting = "false", 0);
      
    • 手动调用变更检测

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

    【讨论】:

    • 嗯,这很尴尬。我没有错误并且尝试了第一个解决方案,但是您使用ChangeDetectionRef 的解决方案让我意识到我已将ChangeDetectionStrategy 设置为OnPush。这就是问题所在!非常感谢您的帮助!
    • 与 onPush 有同样的问题。 Observables 在 console.log 中触发,但在模板中没有触发。禁用 onPush,现在模板已更新。
    • ChangeDetectorRef,不是ChangeDetectionRef
    • 我遇到了动画问题。解决方案是删除 ChangeDetectorRef 并执行 OP 正在尝试的操作:将其包装在 ngZone.run 中。
    • @ArpitAgarwal ngZone.run() 在 Angular 区域中运行代码,而不是在它之外 -> 请参阅 angular.io/api/core/NgZone#run 据我了解,它在那里运行在可以说,角区返回到角区。要在外部运行代码,您可以调用 ngZone.runOutsideAngular()
    【解决方案2】:

    你也可以试试这个解决方案:Guide from Thoughtram

    短版:

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

    你很好。

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

    【讨论】:

    • 为什么通过subscribe 更改的值不会触发更改检测?这是我可以用 rxjs 中的“调度程序”概念来管理的吗?
    • 是否有文档知道为什么通过 .subscribe() 角度更改值不会启动其更改检测?
    【解决方案3】:

    您可以通过 changeDetection 切换(打开/关闭)模板更新。您必须将您选择的策略放入组件定义中。您可以选择 Default 或 OnPush 策略。

    @Component({
        selector: '...............',
        templateUrl: '.......html',
        styleUrls: ['..........scss'],
        changeDetection: ChangeDetectionStrategy.Default
    })
    

    【讨论】:

      【解决方案4】:

      如果您在表达式 *ngIf 中使用它,请记住 *ngIf = false 将无法用作您需要添加的表达式

      <ul *ngIf=" somefunction(x) ? false: true">
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-04-07
        • 2018-01-24
        • 2019-04-27
        • 2019-06-05
        • 2016-12-11
        • 1970-01-01
        • 1970-01-01
        • 2018-11-29
        相关资源
        最近更新 更多