web-dev-qa-db-ja.com

Angular 4現在の時刻を表示

angular 4変更検出システムで現在の時刻を表示する正しい(標準的な)方法は何ですか?

問題は次のとおりです。現在の時間は、定義により常に刻々と変化します。ただし、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);
    }
}
10
BOPOHOB

まず、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);
    });
  }
}
21
cyr_x

AngularドキュメンテーションDatePipeLink に従って、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);
    }
}
11
mrOak
today: number = Date.now();

constructor() {
    setInterval(() => {this.today = Date.now()}, 1);
}

これをhtmlページでフォーマットする場合は、次のように使用します。

<p>{{today | date:'fullDate'}} {{today | date:'h:mm:ss a'}}</p>
1
Jinto Antony

実際、この単純なタスクにはライブラリは必要ありません。 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

1
Oliver
CurrentTime: any;
  constructor() {
    setInterval(() => {
      this.CurrentTime = new Date().getHours() + ':' + new Date().getMinutes() + ':'+  new Date().getSeconds()}, 1);
  }
1
Bruce Smile