角度4显示当前时间

BOP*_*HOB 11 javascript rxjs zonejs angular

在角度4变化检测系统中显示当前时间的正确(规范)方法是什么?

问题如下:根据定义,当前时间每个时刻都在不断变化.但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,你应该使用runOutsideAngularNgZone和使用手动更新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)


Oli*_*ver 6

实际上,这个简单的任务不需要任何库。如果您在使用 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


Jin*_*ony 5

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)