Preciso de um cronômetro no Angular 2, que marque após um intervalo de tempo e faça alguma tarefa (pode ser chamada de algumas funções).
Como fazer isso com o Angular 2?
Preciso de um cronômetro no Angular 2, que marque após um intervalo de tempo e faça alguma tarefa (pode ser chamada de algumas funções).
Como fazer isso com o Angular 2?
Respostas:
Além de todas as respostas anteriores, eu faria isso usando RxJS Observables
verifique Observable.timer
Aqui está um código de amostra, começará após 2 segundos e, em seguida, avança a cada segundo:
import {Component} from 'angular2/core';
import {Observable} from 'rxjs/Rx';
@Component({
selector: 'my-app',
template: 'Ticks (every second) : {{ticks}}'
})
export class AppComponent {
ticks =0;
ngOnInit(){
let timer = Observable.timer(2000,1000);
timer.subscribe(t=>this.ticks = t);
}
}
E aqui está um êmbolo de trabalho
Atualizar Se quiser chamar uma função declarada na classe AppComponent, você pode fazer o seguinte:
** Supondo que a função que você deseja chamar seja chamada de func ,
ngOnInit(){
let timer = Observable.timer(2000,1000);
timer.subscribe(this.func);
}
O problema com a abordagem acima é que se você chamar 'this' dentro de func, ele se referirá ao objeto assinante em vez do objeto AppComponent, que provavelmente não é o que você deseja.
No entanto, na abordagem a seguir, você cria uma expressão lambda e chama a função func dentro dela. Dessa forma, a chamada para func ainda está dentro do escopo do AppComponent. Esta é a melhor forma de o fazer na minha opinião.
ngOnInit(){
let timer = Observable.timer(2000,1000);
timer.subscribe(t=> {
this.func(t);
});
}
verifique este plunker para código de trabalho.
timerparece usar setInterval(). Mas, você pode passar o animationFrameplanejador (que usa requestAnimationFrame()) para usá-lo em vez do asyncplanejador padrão . Tudo que você precisa fazer é Observable.timer(*,*,Scheduler.animationFrame), dado import {Scheduler} from ‘rxjs’.Embora, timernele não pareça funcionar. Ainda parece usar setInterVal(). No entanto, em outros tipos de observáveis, como Observable.range(0,1000,Scheduler.animationFrame), o requestAnimationFrameé usado com certeza. Em termos de desempenho, não posso responder com certeza agora.
Outra solução é usar TimerObservable
TimerObservable é uma subclasse de Observable.
import {Component, OnInit, OnDestroy} from '@angular/core';
import {Subscription} from "rxjs";
import {TimerObservable} from "rxjs/observable/TimerObservable";
@Component({
selector: 'app-component',
template: '{{tick}}',
})
export class Component implements OnInit, OnDestroy {
private tick: string;
private subscription: Subscription;
constructor() {
}
ngOnInit() {
let timer = TimerObservable.create(2000, 1000);
this.subscription = timer.subscribe(t => {
this.tick = t;
});
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
PS: Não se esqueça de cancelar a assinatura.
this.subscription.unsubscribe();cancela a inscrição.
import {Component, View, OnInit, OnDestroy} from "angular2/core";
import { Observable, Subscription } from 'rxjs/Rx';
@Component({
})
export class NewContactComponent implements OnInit, OnDestroy {
ticks = 0;
private timer;
// Subscription object
private sub: Subscription;
ngOnInit() {
this.timer = Observable.timer(2000,5000);
// subscribing to a observable returns a subscription object
this.sub = this.timer.subscribe(t => this.tickerFunc(t));
}
tickerFunc(tick){
console.log(this);
this.ticks = tick
}
ngOnDestroy(){
console.log("Destroy timer");
// unsubscribe here
this.sub.unsubscribe();
}
}
Com rxjs 6.2.2 e Angular 6.1.7, eu estava recebendo um:
Observable.timer is not a function
erro. Isso foi resolvido substituindo Observable.timerpor timer:
import { timer, Subscription } from 'rxjs';
private myTimerSub: Subscription;
ngOnInit(){
const ti = timer(2000,1000);
this.myTimerSub = ti.subscribe(t => {
console.log("Tick");
});
}
ngOnDestroy() {
this.myTimerSub.unsubscribe();
}
Você pode simplesmente usar o utilitário setInterval e usar a função de seta como retorno de chamada para que thisaponte para a instância do componente.
Por ex:
this.interval = setInterval( () => {
// call your functions like
this.getList();
this.updateInfo();
});
Dentro de seu gancho de ciclo de vida ngOnDestroy, limpe o intervalo.
ngOnDestroy(){
clearInterval(this.interval);
}
Enfrentei um problema que tive que usar um timer, mas tive que exibi-los em 2 componentes ao mesmo tempo, mesma tela. Criei o timerObservable em um serviço. Assinei o cronômetro em ambos os componentes, e o que aconteceu? Não será sincronizado, porque uma nova assinatura sempre cria seu próprio fluxo.
O que eu gostaria de dizer, é que se você planeja usar um timer em vários lugares, coloque sempre .publishReplay(1).refCount()
no final do Observer, pois ele publicará o mesmo stream fora dele todas as vezes.
Exemplo:
this.startDateTimer = Observable.combineLatest(this.timer, this.startDate$, (localTimer, startDate) => {
return this.calculateTime(startDate);
}).publishReplay(1).refCount();
Encontrou um pacote npm que facilita isso com RxJS como um serviço.
https://www.npmjs.com/package/ng2-simple-timer
Você pode 'assinar' um cronômetro existente para não criar um bazilhão de cronômetros se estiver usando-o muitas vezes no mesmo componente.
Se você deseja executar um método no ngOnInit, pode fazer algo assim:
importe estas 2 bibliotecas de RXJS:
import {Observable} from 'rxjs/Rx';
import {Subscription} from "rxjs";
Em seguida, declare o temporizador e a assinatura privada, por exemplo:
timer= Observable.timer(1000,1000); // 1 second for 2 seconds (2000,1000) etc
private subscription: Subscription;
Por último, mas não menos importante, execute o método quando o cronômetro parar
ngOnInit() {
this.subscription = this.timer.subscribe(ticks=> {
this.populatecombobox(); //example calling a method that populates a combobox
this.subscription.unsubscribe(); //you need to unsubscribe or it will run infinite times
});
}
Isso é tudo, Angular 5
Set Timer and auto call service after certain time
// Initialize from ngInit
ngOnInit(): void {this.getNotifications();}
getNotifications() {
setInterval(() => {this.getNewNotifications();
}, 60000); // 60000 milliseconds interval
}
getNewNotifications() {
this.notifyService.getNewNotifications().subscribe(
data => { // call back },
error => { },
);
}