問題は次のとおりです。現在の時間は、定義により常に刻々と変化します。ただし、Angular 4変更検出システムでは検出できません。このため、私の意見では、ChangeDetectorRef::detectChanges
を明示的に呼び出す必要があります。ただし、このメソッドを呼び出す過程で、現在の時刻はその値を自然に変更します。これはExpressionChangedAfterItHasBeenCheckedError
につながります。次の例( liveを参照 )では、ページをロードしてから数秒後にこのエラーが表示されます。
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);
}
}
まず、angularはZone.js
を使用しているため、ChangeDetectorRef.detectChanges()
を呼び出す必要はありません。これは、サルがブラウザに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);
}
}
ただし、日付が更新されるたびにangularがコンポーネントツリーで変更検出を実行するため、パフォーマンスが低下するため、このような高いレートで時間を更新しないでください。
DOMを非常に高いレートで更新する場合は、runOutsideAngular
からNgZone
を使用し、Renderer2
を使用してDOMを手動で更新する必要があります。
例えば:
@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);
});
}
}
AngularドキュメンテーションDatePipe
Link に従って、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);
}
}
today: number = Date.now();
constructor() {
setInterval(() => {this.today = Date.now()}, 1);
}
これをhtmlページでフォーマットする場合は、次のように使用します。
<p>{{today | date:'fullDate'}} {{today | date:'h:mm:ss a'}}</p>
実際、この単純なタスクにはライブラリは必要ありません。 angularプロジェクトでangular 6+を使用している場合は、共通パッケージから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');
}
}
ここにstackblitzリンクがあります、ここで編集できます: https://stackblitz.com/edit/angular-h63y8e
CurrentTime: any;
constructor() {
setInterval(() => {
this.CurrentTime = new Date().getHours() + ':' + new Date().getMinutes() + ':'+ new Date().getSeconds()}, 1);
}