在 Angular 4 变化检测系统中显示当前时间的正确(规范)方法是什么?
问题如下:根据定义,当前时间每时每刻都在不断变化。但 Angular 4 变更检测系统无法检测到它。因此,我认为有必要明确调用ChangeDetectorRef::detectChanges
。然而,在调用这个方法的过程中,当前时间自然会改变它的值。这导致ExpressionChangedAfterItHasBeenCheckedError
。在以下示例中(see live https://angular-tlpmtr.stackblitz.io)加载页面后几秒钟内就会出现此错误:
import { Component, ChangeDetectorRef } from '@angular/core';
@Component({
selector: 'my-app',
template: `{{ now }}<br />{{ now }}<br />{{ now }}<br />{{ now }}<br />{{ now }}<br />{{ now }}<br />
{{ now }}<br />{{ now }}<br />{{ now }}<br />{{ now }}<br />{{ now }}<br />{{ now }}<br />
{{ now }}<br />{{ now }}<br />{{ now }}<br />{{ now }}<br />{{ now }}<br />{{ now }}<br />
{{ now }}<br />{{ now }}<br />{{ now }}<br />{{ now }}<br />{{ now }}<br />{{ now }}<br />
{{ now }}<br />{{ now }}<br />{{ now }}<br />{{ now }}<br />{{ now }}<br />{{ now }}<br />
{{ now }}<br />{{ now }}<br />{{ now }}<br />{{ now }}<br />{{ now }}<br />{{ now }}<br />
{{ now }}<br />{{ now }}<br />{{ now }}<br />{{ now }}<br />{{ now }}<br />{{ now }}<br />
{{ now }}<br />{{ now }}<br />{{ now }}<br />{{ now }}<br />{{ now }}<br />{{ now }}`
})
export class AppComponent {
get now() : string { return Date(); }
constructor(cd: ChangeDetectorRef) {
setInterval(function() { cd.detectChanges(); }, 1);
}
}
首先你不需要打电话ChangeDetectorRef.detectChanges()
在你的间隔内,因为角度正在使用Zone.js
哪只猴子给浏览器打补丁setInteral
有自己的方法。因此,Angular 很清楚在一个时间间隔内发生的变化。
您应该像这样设置间隔内的时间:
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `{{ now }}`
})
export class AppComponent {
public now: Date = new Date();
constructor() {
setInterval(() => {
this.now = new Date();
}, 1);
}
}
但是您不应该以如此高的速率更新时间,因为这会导致性能不佳,因为每次更新日期时,角度都会在组件树上执行更改检测。
如果你想以非常高的速率更新 DOM,你应该使用runOutsideAngular
from NgZone
并使用以下命令手动更新 DOMRenderer2
.
例如:
@Component({
selector: 'my-counter',
template: '<span #counter></span>'
})
class CounterComponent implements OnChange {
public count: number = 0;
@ViewChild('counter')
public myCounter: ElementRef;
constructor(private zone: NgZone, private renderer: Renderer2) {
this.zone.runOutsideAngular(() => {
setInterval(() => {
this.renderer.setProperty(this.myCounter.nativeElement, 'textContent', ++this.count);
}, 1);
});
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)