Tôi cần một bộ đếm thời gian trong Angular 2, đánh dấu sau một khoảng thời gian và thực hiện một số tác vụ (có thể gọi một số chức năng).
Làm thế nào để làm điều này với Angular 2?
Tôi cần một bộ đếm thời gian trong Angular 2, đánh dấu sau một khoảng thời gian và thực hiện một số tác vụ (có thể gọi một số chức năng).
Làm thế nào để làm điều này với Angular 2?
Câu trả lời:
Ngoài tất cả các câu trả lời trước đó, tôi sẽ làm điều đó bằng cách sử dụng RxJS Observables
vui lòng kiểm tra Observable.timer
Đây là mã mẫu, sẽ bắt đầu sau 2 giây và sau đó tích tắc mỗi giây:
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);
}
}
Và đây là một thợ đào đang hoạt động
Cập nhật Nếu bạn muốn gọi một hàm được khai báo trên lớp AppComponent, bạn có thể thực hiện một trong các thao tác sau:
** Giả sử hàm bạn muốn gọi có tên là func ,
ngOnInit(){
let timer = Observable.timer(2000,1000);
timer.subscribe(this.func);
}
Vấn đề với cách tiếp cận trên là nếu bạn gọi 'this' bên trong func, nó sẽ tham chiếu đến đối tượng người đăng ký thay vì đối tượng AppComponent có thể không phải là điều bạn muốn.
Tuy nhiên, trong cách tiếp cận dưới đây, bạn tạo một biểu thức lambda và gọi hàm func bên trong nó. Bằng cách này, lệnh gọi đến func vẫn nằm trong phạm vi của AppComponent. Đây là cách tốt nhất để làm điều đó theo ý kiến của tôi.
ngOnInit(){
let timer = Observable.timer(2000,1000);
timer.subscribe(t=> {
this.func(t);
});
}
kiểm tra mã hoạt động của plunker này .
timer
dường như sử dụng setInterval()
. Tuy nhiên, bạn có thể chuyển bộ lập animationFrame
lịch (mà sử dụng requestAnimationFrame()
) để sử dụng nó thay vì bộ lập async
lịch mặc định . Tất cả những gì bạn cần làm là Observable.timer(*,*,Scheduler.animationFrame)
, mặc import {Scheduler} from ‘rxjs’
dù, timer
nó dường như không hoạt động. Nó dường như vẫn sử dụng setInterVal()
. Tuy nhiên, trên các loại có thể quan sát khác, chẳng hạn Observable.range(0,1000,Scheduler.animationFrame)
, requestAnimationFrame
được sử dụng chắc chắn. hiệu suất khôn ngoan, tôi không thể trả lời bạn chắc chắn ngay bây giờ.
Một giải pháp khác là sử dụng TimerObservable
TimerObservable là một lớp con của 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();
}
}
Tái bút: Đừng quên hủy đăng ký.
this.subscription.unsubscribe();
hủy đăng ký thành phần: hủy đăng ký.
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();
}
}
Với rxjs 6.2.2 và Angular 6.1.7, tôi nhận được:
Observable.timer is not a function
lỗi. Điều này đã được giải quyết bằng cách thay thế Observable.timer
bằng 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();
}
Bạn có thể chỉ cần sử dụng tiện ích setInterval và sử dụng hàm mũi tên làm lệnh gọi lại để nó this
sẽ trỏ đến cá thể thành phần.
Đối với ví dụ:
this.interval = setInterval( () => {
// call your functions like
this.getList();
this.updateInfo();
});
Bên trong móc vòng đời ngOnDestroy của bạn, xóa khoảng thời gian.
ngOnDestroy(){
clearInterval(this.interval);
}
Tôi gặp phải một vấn đề là tôi phải sử dụng bộ hẹn giờ, nhưng tôi phải hiển thị chúng trong 2 thành phần cùng một lúc, cùng một màn hình. Tôi đã tạo bộ hẹn giờ Có thể quan sát trong một dịch vụ. Tôi đã đăng ký bộ hẹn giờ trong cả hai thành phần và điều gì đã xảy ra? Nó sẽ không được đồng bộ hóa, vì đăng ký mới luôn tạo luồng riêng.
Điều tôi muốn nói, là nếu bạn định sử dụng một bộ đếm thời gian ở một số nơi, hãy luôn đặt .publishReplay(1).refCount()
ở cuối Trình quan sát, vì nó sẽ xuất bản cùng một luồng ra khỏi đó mọi lúc.
Thí dụ:
this.startDateTimer = Observable.combineLatest(this.timer, this.startDate$, (localTimer, startDate) => {
return this.calculateTime(startDate);
}).publishReplay(1).refCount();
Đã tìm thấy một gói npm giúp việc này trở nên dễ dàng với RxJS như một dịch vụ.
https://www.npmjs.com/package/ng2-simple-timer
Bạn có thể 'đăng ký' vào một bộ đếm thời gian hiện có để không tạo ra một bộ hẹn giờ bazillion nếu bạn đang sử dụng nó nhiều lần trong cùng một thành phần.
Nếu bạn muốn chạy một phương thức trên ngOnInit, bạn có thể làm như sau:
nhập 2 thư viện này từ RXJS:
import {Observable} from 'rxjs/Rx';
import {Subscription} from "rxjs";
Sau đó khai báo bộ hẹn giờ và đăng ký riêng tư, ví dụ:
timer= Observable.timer(1000,1000); // 1 second for 2 seconds (2000,1000) etc
private subscription: Subscription;
Phương pháp chạy cuối cùng nhưng không kém phần quan trọng khi bộ đếm thời gian dừng
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
});
}
Đó là tất cả, 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 => { },
);
}