Potrzebuję timera w Angular 2, który tyka po pewnym czasie i wykonuję jakieś zadanie (może być wywołanie niektórych funkcji).
Jak to zrobić w Angular 2?
Potrzebuję timera w Angular 2, który tyka po pewnym czasie i wykonuję jakieś zadanie (może być wywołanie niektórych funkcji).
Jak to zrobić w Angular 2?
Odpowiedzi:
Oprócz wszystkich poprzednich odpowiedzi zrobiłbym to za pomocą RxJS Observables
sprawdź Observable.timer
Oto przykładowy kod, który rozpocznie się po 2 sekundach, a następnie będzie zaznaczony co sekundę:
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);
}
}
A oto pracujący plunker
Aktualizacja Jeśli chcesz wywołać funkcję zadeklarowaną w klasie AppComponent, możesz wykonać jedną z następujących czynności:
** Zakładając, że funkcja, którą chcesz wywołać, nazywa się func ,
ngOnInit(){
let timer = Observable.timer(2000,1000);
timer.subscribe(this.func);
}
Problem z powyższym podejściem polega na tym, że jeśli wywołasz „this” wewnątrz funkcji func, odniesie się ono do obiektu subskrybenta zamiast do obiektu AppComponent, co prawdopodobnie nie jest tym, czego chcesz.
Jednak w poniższym podejściu tworzysz wyrażenie lambda i wywołujesz w nim funkcję func . W ten sposób wywołanie func nadal znajduje się w zakresie AppComponent. Moim zdaniem to najlepszy sposób na zrobienie tego.
ngOnInit(){
let timer = Observable.timer(2000,1000);
timer.subscribe(t=> {
this.func(t);
});
}
sprawdź ten plunker pod kątem działającego kodu.
timer
wydaje się , że używa setInterval()
. Ale możesz przekazać animationFrame
harmonogram (który używa requestAnimationFrame()
), aby go używał zamiast domyślnego async
harmonogramu. Wszystko, co musisz zrobić, to Observable.timer(*,*,Scheduler.animationFrame)
dane, import {Scheduler} from ‘rxjs’
chociaż wydaje się, timer
że nie działa. Nadal wydaje się używać setInterVal()
. Jednak w przypadku innych rodzajów obserwowalnych, takich jak Observable.range(0,1000,Scheduler.animationFrame)
, z requestAnimationFrame
pewnością jest używany. Jeśli chodzi o wydajność, nie mogę ci teraz odpowiedzieć na pewno.
Innym rozwiązaniem jest użycie TimerObservable
TimerObservable jest podklasą 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: Nie zapomnij wypisać się.
this.subscription.unsubscribe();
unsubscribes.
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();
}
}
Z rxjs 6.2.2 i Angular 6.1.7 otrzymywałem:
Observable.timer is not a function
błąd. Ten problem został rozwiązany przez zastąpienie Observable.timer
z 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();
}
Możesz po prostu użyć narzędzia setInterval i użyć funkcji strzałki jako wywołania zwrotnego, aby this
wskazywała na instancję komponentu.
Na przykład:
this.interval = setInterval( () => {
// call your functions like
this.getList();
this.updateInfo();
});
Wewnątrz haka cyklu życia ngOnDestroy wyczyść interwał.
ngOnDestroy(){
clearInterval(this.interval);
}
Napotkałem problem polegający na tym, że musiałem użyć timera, ale musiałem wyświetlić je w tym samym czasie w 2 komponentach, na tym samym ekranie. Utworzyłem timer obserwowalny w usłudze. Zasubskrybowałem licznik czasu w obu komponentach i co się stało? Nie zostanie zsynchronizowany, ponieważ nowa subskrypcja zawsze tworzy własny strumień.
Chciałabym powiedzieć, że jeśli planujesz używać jednego timera w kilku miejscach, zawsze umieszczaj go .publishReplay(1).refCount()
na końcu Observera, ponieważ za każdym razem będzie on publikował z niego ten sam strumień.
Przykład:
this.startDateTimer = Observable.combineLatest(this.timer, this.startDate$, (localTimer, startDate) => {
return this.calculateTime(startDate);
}).publishReplay(1).refCount();
Znalazłem pakiet npm, który ułatwia to dzięki RxJS jako usłudze.
https://www.npmjs.com/package/ng2-simple-timer
Możesz `` zasubskrybować '' istniejący zegar, aby nie tworzyć miliardów zegarów, jeśli używasz go wiele razy w tym samym komponencie.
Jeśli chcesz uruchomić metodę w ngOnInit, możesz zrobić coś takiego:
zaimportuj te 2 biblioteki z RXJS:
import {Observable} from 'rxjs/Rx';
import {Subscription} from "rxjs";
Następnie zadeklaruj licznik czasu i subskrypcję prywatną, przykład:
timer= Observable.timer(1000,1000); // 1 second for 2 seconds (2000,1000) etc
private subscription: Subscription;
Ostatnia, ale nie mniej ważna metoda uruchamiania po zatrzymaniu timera
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
});
}
To wszystko, 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 => { },
);
}