4

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

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

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

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

在 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() 成功使 OnChanges 挂钩在 ProgressBarComponent 中触发。组件和模板如下图所示:

零件

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 正在触发,并且值是正确的。我读过的所有内容都说“一旦检测到更改,视图就会自动更新”,所以我不知道还能做什么。

有什么建议么?

4

2 回答 2

0

完成异步任务后,您将使用以下行覆盖您从订阅中收到的数据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();
   },
}
于 2017-05-02T15:20:18.047 回答
-1

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

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

于 2020-12-28T06:42:29.323 回答