BOP*_*HOB 11 javascript rxjs zonejs angular
问题如下:根据定义,当前时间每个时刻都在不断变化.但Angular 4变化检测系统无法检测到它.出于这个原因,在我看来,有必要明确地打电话ChangeDetectorRef::detectChanges.但是,在调用此方法的过程中,当前时间自然会改变其值.这导致了ExpressionChangedAfterItHasBeenCheckedError.在以下示例中(请参阅实时),加载页面后几秒钟会出现此错误:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
cyr*_*r_x 22
首先,你不需要ChangeDetectorRef.detectChanges()在你的间隔内调用,因为angular使用Zone.js哪个猴子修补了浏览器setInteral方法.因此,角度非常清楚间隔期间发生的变化.
你应该在你的间隔内设置这样的时间:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
但是你不应该以如此高的速率更新时间,因为它会导致性能不佳,因为每次更新角度时角度都会在组件树上执行更改检测.
如果你想在一个非常高的速度来更新DOM,你应该使用runOutsideAngular从NgZone和使用手动更新DOM Renderer2.
例如:
@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);
});
}
}
Run Code Online (Sandbox Code Playgroud)
小智 11
根据DatePipe Link上的Angular文档,Date.now()可以使用.
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `{{ now | date:'HH:mm:ss'}}`
})
export class AppComponent {
now:number;
constructor() {
setInterval(() => {
this.now = Date.now();
}, 1);
}
}
Run Code Online (Sandbox Code Playgroud)
实际上,这个简单的任务不需要任何库。如果您在使用 angular 6+ 的 angular 项目中进行操作,则从公共包中导入 formatDate 并传递其他数据。这是一个示例:
import { Component } from '@angular/core';
import {formatDate } from '@angular/common';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
today= new Date();
todaysDataTime = '';
constructor() {
this.todaysDataTime = formatDate(this.today, 'dd-MM-yyyy hh:mm:ss a', 'en-US', '+0530');
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个stackblitz链接,你可以在这里编辑:https ://stackblitz.com/edit/angular-h63y8e
today: number = Date.now();
constructor() {
setInterval(() => {this.today = Date.now()}, 1);
}
Run Code Online (Sandbox Code Playgroud)
如果你想在 html 页面上设置它的格式,请像这样使用它:
<p>{{today | date:'fullDate'}} {{today | date:'h:mm:ss a'}}</p>
Run Code Online (Sandbox Code Playgroud)
我再添加一点,这是我发现的,并且由于这个答案而可能更接近我的解决方案,因此对于另一个正在寻求类似事物的人,我也添加了这一点:)
如果您想获得包含所有数字的 [Year: Month :date :hours: 分钟 with am/pm ] 格式(例如 : 12 而不是字符串“December”),只需使用以下命令
<p>{{today | date:'y:M:d:h:mm a'}}</p>
Run Code Online (Sandbox Code Playgroud)