【问题标题】:Angular ngOnChanges not updating viewAngular ngOnChanges 不更新视图
【发布时间】:2017-09-30 04:27:50
【问题描述】:

TL;DR:ngOnChanges 表明正在检测输入属性的更改,但视图未更新

我正在开发一个 Angular (2+) 应用程序,试图为使用 Observable 的服务完成的异步任务制作进度条。 Observable 将数字作为数据推送,以指示已完成任务的百分比。涉及三个部分:Service、ResultsComponent 和 ProgressBarComponent(ResultsComponent 的子级) 基本数据流是:

  1. 从 Observable 推送到 ResultsComponent 的数字
  2. ResultsComponent.percentLoaded 设置为等于此数字
  3. ProgressBarComponent 使用 percentLoaded 作为输入并更新视图

问题是视图实际上并没有被更新。

在 ResultsComponent 我有这个块:

this.service.doTheTask()
    .subscribe(
      data => {
        this.percentLoaded = data;
        this.ref.detectChanges();
      },
      e => console.log('error:', e),
      () =>  {
        this.isLoading = false;
        this.percentLoaded = 0;
      }
    );

成功添加 ref.detectChanges() 会在 ProgressBarComponent 中触发 OnChanges 挂钩。组件和模板如下所示:

组件

export class ProgressBarComponent implements OnChanges {
  @Input() percentLoaded = 0;

  constructor() { }

  ngOnChanges(changes) {
    console.log('changes: ', changes);
  }
}

模板

<div class="meter">
  <div class="percent" [style.width.%]="percentLoaded"></div>
</div>
<p>{{percentLoaded}}% Loaded</p>

如您所见,我只是记录更改以进行测试。我已经验证 ngOnChanges 正在触发,并且值是正确的。我读过的所有内容都说“一旦检测到更改,视图就会自动更新”,所以我不知道还能做什么。

有什么建议吗?

【问题讨论】:

  • 视图中的percentLoaded字段的绑定是否都没有更新,或者只是其中的一些?
  • 在 observable 完成之前,视图中不会显示任何绑定。我在回调中设置 this.percentLoaded = 0 以完成 observable。那个显示在视图中。如果我删除该行,视图将更新为显示 100,这是从 observable 推送的最后一个值。

标签: angular typescript angular2-template ngonchanges


【解决方案1】:

完成异步任务后,您将使用以下行 this.percentLoaded = 0; 覆盖您从订阅中收到的数据。删除它:

() =>  {
   this.isLoading = false;
   //delete this line this.percentLoaded = 0;
}

您的更改检测也不会被触发,因为只有在对象的引用发生更改时才会触发对输入的更改检测。 Number 是一个简单的,而不是参考变量,因此在您的情况下不会触发更改检测。我的建议是订阅两个组件中的服务并仅从子组件触发更改检测。

export class ProgressBarComponent {
  percentLoaded: number = 0;

  constructor(private ref: ChangeDetectorRef, private service: TheService) { }

  this.service.doTheTask()
   .subscribe(
     data => {
     this.percentLoaded = data;
     this.ref.detectChanges();
   },
}

【讨论】:

  • 当我这样做时,在 observable 的执行过程中视图仍然没有更新。它获取 100(返回的最后一个值)并更新视图以显示该值,但仅在 observable 完成之后。
  • 所以你是说这里还没有触发变更检测?在上面的代码中,每次到达 OnChanges 挂钩时我都会记录。它显示了 0 到 100 之间的每个中间值。如果您说更改检测仍未被触发,那么我对 OnChanges 挂钩的含义感到困惑。
【解决方案2】:

我遇到了类似的问题,在花了大约一个小时试图弄清楚之后,我记得在父组件中添加了更改检测策略 onPush。

一旦我删除了子组件,它就会再次开始工作。 ngOnChanges 方法正在触发,但我的视图没有在订阅闭包中更新。

【讨论】:

    猜你喜欢
    • 2019-08-24
    • 2020-06-17
    • 1970-01-01
    • 2018-12-25
    • 2018-08-29
    • 1970-01-01
    • 2021-10-08
    • 1970-01-01
    • 2017-11-28
    相关资源
    最近更新 更多