Angular中ChangeDetectorRef实时渲染失效:仅自增一次问题排查
问题原因
你使用的 timer(1000) 只会延迟1秒后执行一次,因此数值仅递增1次就停止。要实现每秒重复触发的效果,需要给 timer 传入第二个参数指定间隔时间。
修复方案
修改 ngOnInit 中的 timer 调用,改为 timer(0, 1000)——第一个参数 0 表示立即启动执行,第二个参数 1000 表示每隔1秒重复触发:
import { Component, OnInit, ChangeDetectionStrategy, ChangeDetectorRef, } from '@angular/core'; import { timer } from 'rxjs'; import { tap } from 'rxjs/operators'; @Component({ selector: 'my-app', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], changeDetection: ChangeDetectionStrategy.OnPush, }) export class AppComponent implements OnInit { constructor(private cdr: ChangeDetectorRef) {} item = 0; ngOnInit(): void { // 0:立即执行,1000:每隔1秒重复触发 timer(0, 1000) .pipe( tap(() => { this.item++; this.cdr.markForCheck(); }) ) .subscribe(); } }
更优雅的实现(无需手动管理变更检测)
既然使用了 OnPush 变更检测,推荐将 item 改为 Observable,直接在模板中用 async 管道绑定,Angular 会自动处理变更检测,无需手动调用 cdr.markForCheck():
import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { timer } from 'rxjs'; import { scan } from 'rxjs/operators'; @Component({ selector: 'my-app', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], changeDetection: ChangeDetectionStrategy.OnPush, }) export class AppComponent implements OnInit { item$ = timer(0, 1000).pipe(scan((acc) => acc + 1, 0)); }
模板中绑定代码:
{{ item$ | async }}
这种方式更贴合 Angular 响应式编程理念,同时避免了手动管理变更检测的冗余操作。
内容的提问来源于stack exchange,提问作者Ahmad Barutchi
相关产品推荐
相关产品推荐

