web-dev-qa-db-de.com

Winkel 4 zeigt die aktuelle Uhrzeit an

Was ist der richtige (kanonische) Weg, um die aktuelle Zeit in einem Winkeländerungs-Erkennungssystem anzuzeigen?

Das Problem ist wie folgt: Die aktuelle Zeit ändert sich ständig, jeden Moment per Definition. Es ist jedoch nicht mit dem Änderungserkennungssystem Angular 4 erkennbar. Aus diesem Grund muss meiner Meinung nach explizit ChangeDetectorRef::detectChanges aufgerufen werden. Beim Aufrufen dieser Methode ändert die aktuelle Zeit natürlich ihren Wert. Dies führt zu ExpressionChangedAfterItHasBeenCheckedError. Im folgenden Beispiel ( siehe live ) tritt dieser Fehler einige Sekunden nach dem Laden der Seite auf:

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);
    }
}
8
BOPOHOB

Zuallererst brauchen Sie ChangeDetectorRef.detectChanges() nicht innerhalb Ihres Intervalls aufzurufen, da angle Zone.js verwendet, der Affe die setInteral-Methode des Browsers mit einer eigenen Patches ausfüllt. Daher ist sich winklig der Änderungen bewusst, die während eines Intervalls stattfinden.

Sie sollten die Zeit in Ihrem Intervall folgendermaßen einstellen:

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);
    }
}

Sie sollten die Uhrzeit jedoch nicht auf eine so hohe Rate aktualisieren, da dies zu einer schlechten Leistung führen würde, da jedes Mal, wenn die Datumsaktualisierungen aktualisiert werden, Winkel eine Änderung im Komponentenbaum durchführt.

Wenn Sie das DOM mit einer sehr hohen Geschwindigkeit aktualisieren möchten, sollten Sie runOutsideAngular aus NgZone verwenden und das DOM manuell mit dem Renderer2 aktualisieren.

Zum Beispiel:

@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);
    });
  }
}
15
cyr-x

Wie in der Angular-Dokumentation zu DatePipeLink beschrieben, kann Date.now() verwendet werden.

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);
    }
}
6
mrOak
today: number = Date.now();

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

Wenn Sie dies auf einer HTML-Seite formatieren möchten, verwenden Sie es wie folgt:

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

Eigentlich brauchen Sie für diese einfache Aufgabe keine Bibliothek. Wenn Sie in Ihrem Projekt angular= mit angular 6+) arbeiten, importieren Sie formatDate aus dem allgemeinen Paket und übergeben Sie andere Daten. Hier ein Beispiel:

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');
  }
}

Hier ist ein Stackblitz-Link, den Sie hier bearbeiten können: https://stackblitz.com/edit/angular-h63y8e

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