Ответ 1
Как упоминали @Adam и @Ploppy, Observable.interval() теперь не рекомендуется, а не является предпочтительным способом создания такой наблюдаемой. Предпочтительный способ сделать это через IntervalObservable или TimerObservable. [в настоящее время в Typscript 2.5.2, rxjs 5.4.3, Angular 4.0.0]
Я хотел добавить немного использования в этот ответ, чтобы продемонстрировать, как я нашел лучший способ сделать это в среде Angular 2.
Сначала ваш сервис (созданный в angular cli с помощью команды 'ng g service MyExample "). Предполагается, что сервис RESTful (запрос http get возвращает json):
мой-example.service.ts
import { Injectable } from '@angular/core';
import { Http, Response} from "@angular/http";
import { MyDataModel } from "./my-data-model";
import { Observable } from "rxjs";
import 'rxjs/Rx';
@Injectable()
export class MyExampleService {
private url = 'http://localhost:3000'; // full uri of the service to consume here
constructor(private http: Http) { }
get(): Observable<MyDataModel>{
return this.http
.get(this.url)
.map((res: Response) => res.json());
}
}
*** смотрите нижние обновления к сервису для Angular 5 ***
Теперь ваш код компонента ('ng g component MyExample'):
мой-example.component.ts:
import { Component, OnDestroy, OnInit } from '@angular/core';
import { MyDataModel } from "../my-data-model";
import { MyExampleService } from "../my-example.service";
import { Observable } from "rxjs";
import { IntervalObservable } from "rxjs/observable/IntervalObservable";
import 'rxjs/add/operator/takeWhile';
@Component({
selector: 'app-my-example',
templateUrl: './my-example.component.html',
styleUrls: ['./my-example.component.css']
})
export class MyExampleComponent implements OnInit, OnDestroy {
private data: MyDataModel;
private display: boolean; // whether to display info in the component
// use *ngIf="display" in your html to take
// advantage of this
private alive: boolean; // used to unsubscribe from the IntervalObservable
// when OnDestroy is called.
constructor(private myExampleService: MyExampleService) {
this.display = false;
this.alive = true;
}
ngOnInit() {
// get our data immediately when the component inits
this.myExampleService.get()
.first() // only gets fired once
.subscribe((data) => {
this.data = data;
this.display = true;
});
// get our data every subsequent 10 seconds
IntervalObservable.create(10000)
.takeWhile(() => this.alive) // only fires when component is alive
.subscribe(() => {
this.myExampleService.get()
.subscribe(data => {
this.data = data;
});
});
}
ngOnDestroy(){
this.alive = false; // switches your IntervalObservable off
}
}
=== редактировать ===
Обновлен код компонента для объединения подписок с помощью TimerObservable:
import { Component, OnDestroy, OnInit } from '@angular/core';
import { MyDataModel } from "../my-data-model";
import { MyExampleService } from "../my-example.service";
import { Observable } from "rxjs";
import { TimerObservable } from "rxjs/observable/TimerObservable";
import 'rxjs/add/operator/takeWhile';
@Component({
selector: 'app-my-example',
templateUrl: './my-example.component.html',
styleUrls: ['./my-example.component.css']
})
export class MyExampleComponent implements OnInit, OnDestroy {
private data: MyDataModel;
private display: boolean; // whether to display info in the component
// use *ngIf="display" in your html to take
// advantage of this
private alive: boolean; // used to unsubscribe from the TimerObservable
// when OnDestroy is called.
private interval: number;
constructor(private myExampleService: MyExampleService) {
this.display = false;
this.alive = true;
this.interval = 10000;
}
ngOnInit() {
TimerObservable.create(0, this.interval)
.takeWhile(() => this.alive)
.subscribe(() => {
this.myExampleService.get()
.subscribe((data) => {
this.data = data;
if(!this.display){
this.display = true;
}
});
});
}
ngOnDestroy(){
this.alive = false; // switches your TimerObservable off
}
}
=== редактировать ===
my-example-service.ts (используя HttpClient в стиле Angular 5):
import { Injectable } from '@angular/core';
import { HttpClient} from "@angular/common/http";
import { MyDataModel } from "./my-data-model";
import { Observable } from "rxjs";
import 'rxjs/Rx';
@Injectable()
export class MyExampleService {
private url = 'http://localhost:3000'; // full uri of the service to consume here
constructor(private http: HttpClient) { }
get(): Observable<MyDataModel>{
return this.http
.get<MyDataModel>(this.url);
}
}
Заметьте, что измените использование HttpClient вместо Http (устарело в angular5) и метода get, который позволяет анализировать ответ в нашей модели данных без использования оператора rxjs.map(). В то время как услуга изменяется на угловую 5, код компонента остается неизменным.