Angular2 + http 간격
저는 angular와 rxjs에 아주 익숙합니다. 정적으로 제공되는 텍스트 파일 (Locally on server)에서 일부 데이터를 가져 오는 angular2 앱을 만들려고합니다 .Angular2의 http 공급자와 rxjs의지도를 사용하여 고정 된 시간에 데이터 모델을 검색하고 매핑하고 싶습니다 interval(5000)
. 제공된 txt 파일의 변경 사항을 반영합니다.
rxjs 4.x를 사용 Observable.interval(5000)
하면 작업을 수행하는 데 사용할 수 있지만 rxjs 5에는 존재하지 않는 것 같습니다. 내 해결 방법은 현재 <meta http-equiv="refresh" content="5" >
전체 페이지를 다시로드하여 데이터를 다시로드하는 방법을 사용하여 전체 응용 프로그램을 새로 고칩니다 .
그래서 제가 정말로 원하는 것은 관찰 가능 항목을 사용하여이 작업을 수행하는 방법입니다. 변경 사항이 있는지 확인하는 것입니다. 또는 데이터를 새로 다시로드합니다.
어떤 도움이나 다른 / 더 나은 방법도 대단히 감사하겠습니다.
내가 지금까지 가지고있는 것 :
@Injectable()
export class DataService {
constructor(private http:Http){}
getData(url) {
return this.http.get(url)
.map(res => {
return res.text();
})
.map(res => {
return res.split("\n");
})
.map(res => {
var dataModels: DataModel[] = [];
res.forEach(str => {
var s = str.split(",");
if(s[0] !== "") {
dataModels.push(new DataModel(s[0], parseInt(s[1]), parseInt(s[2])));
}
});
return dataModels;
})
}
}
@Component({
selector: 'my-app',
template: `Some html to display the data`,
providers: [DataService],
export class AppComponent {
data:DataModel[];
constructor(dataService:DataService) {}
ngOnInit() {
this.dataService.getData('url').subscribe(
res => {
this.data= res;
},
err => console.log(err),
() => console.log("Data received")
);
}
}
종속성 : package.json
"dependencies": {
"angular2": "^2.0.0-beta.3",
"bootstrap": "^4.0.0-alpha.2",
"es6-promise": "^3.0.2",
"es6-shim": "^0.33.13",
"jquery": "^2.2.0",
"reflect-metadata": "^0.1.2",
"rxjs": "^5.0.0-beta.0",
"systemjs": "^0.19.20",
"zone.js": "^0.5.11"
},
"devDependencies": {
"typescript": "^1.7.5"
}
index.html 가져 오기 :
<script src="node_modules/es6-shim/es6-shim.min.js"></script>
<script src="node_modules/systemjs/dist/system-polyfills.js"></script>
<script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="node_modules/rxjs/bundles/Rx.js"></script>
<script src="node_modules/angular2/bundles/angular2.dev.js"></script>
<script src="node_modules/angular2/bundles/router.dev.js"></script>
<script src="node_modules/angular2/bundles/http.dev.js"></script>
@Adam 및 @Ploppy가 언급했듯이 Observable.interval ()은 이제
이러한 관찰 가능 항목을 만드는 데 선호되는 방법이 아니라
더 이상 사용되지
않습니다. 이를 수행하는 선호되는 방법은 IntervalObservable 또는 TimerObservable을 사용하는 것입니다. [현재 Typscript 2.5.2, rxjs 5.4.3, Angular 4.0.0]
Angular 2 프레임 워크에서 가장 좋은 방법을 찾은 것을 보여주기 위해이 답변에 몇 가지 사용법을 추가하고 싶었습니다.
먼저 서비스 ( 'ng g service MyExample "명령을 통해 angular cli에서 생성됨). 서비스가 RESTful이라고 가정합니다 (http get 요청이 json을 반환 함).
my-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') :
my-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을 통해 구독을 통합하도록 구성 요소 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 { 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 (Angular 5로 HttpClient 사용) :
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);
}
}
Http (angular5에서 더 이상 사용되지 않음) 대신 HttpClient를 사용하도록 변경하고 rxjs .map () 연산자를 사용하지 않고도 데이터 모델로 응답을 구문 분석 할 수있는 get 메서드를 사용합니다. 각도 5에 대한 서비스가 변경되는 동안 구성 요소 코드는 변경되지 않습니다.
Angular2 내에서 의 interval
방법을 사용할 수 있습니다 Observable
.
import {Component,Input} from 'angular2/core';
import {Observable} from 'rxjs/Rx';
@Component({
selector: 'my-app',
template: `
<div>
{{message}}
</div>
`
})
export class AppComponent {
constructor() {
Observable.interval(500)
.take(10).map((x) => x+1)
.subscribe((x) => {
this.message = x;
}):
}
}
다음은이를 설명하는 해당 plunkr입니다 : https://plnkr.co/edit/pVMEbbGSzMwSBS4XEXJI?p=preview .
이를 기반으로 HTTP 요청을 연결할 수 있습니다.
initializePolling() {
return Observable
.interval(60000)
.flatMap(() => {
return this.dataService.getData('url'));
});
}
이 답변은 rxjs / observable의 최근 변경으로 인해 더 이상 유효하지 않다고 생각합니다. 이제 IntervalObservable을 사용해야합니다.
https://github.com/ReactiveX/rxjs/blob/master/src/observable/IntervalObservable.ts
import { IntervalObservable } from 'rxjs/observable/IntervalObservable';
@Component({
...
})
export class AppComponent {
n: number = 0;
constructor() {
IntervalObservable.create(1000).subscribe(n => this.n = n);
}
}
For TypeScript (1.8.10 at time of answer)/angular2 (rc1 at time of answer) with rxjs@5.0.0 (beta.6 at time of answer) you need to use the IntervalObservable
which extends the Observable
class
import {IntervalObservable} from 'rxjs/observable/IntervalObservable'
IntervalObservable.create(5000).take(10).map((x) => x + 1)
this can be easily done via switchMap
Observable.timer(0, 5000)
.switchMap((t) =>
this.http.get(...).pipe(
catchError(...)
)
)
.subscribe(...)
Disaclaimer: this was originaly an edit for another answer, but contains too many changes.
This can be easily done via switchMap
:
Observable.timer(0, 5000)
.switchMap(() => this.http.get(...).pipe(...)
.subscribe(...)
Or in RxJS 6 syntax:
import { timer } from 'rxjs';
import { switchMap } from 'rxjs/operators';
timer(0, 5000) // repeats every 5 seconds
.pipe(switchMap(() => this.http.get(...).pipe(...))
.subscribe(...);
You can even use a interval
instead of a timer
:
import { interval } from 'rxjs';
import { switchMap } from 'rxjs/operators';
interval(5000) // repeats every 5 seconds
.pipe(switchMap(() => this.http.get(...).pipe(...))
.subscribe(...);
참고URL : https://stackoverflow.com/questions/35316583/angular2-http-at-an-interval
'IT박스' 카테고리의 다른 글
문자열에 PHPUnit의 다른 문자열이 포함되어 있는지 테스트하는 방법은 무엇입니까? (0) | 2020.12.07 |
---|---|
OkHttp 요청 본문을 기록하는 방법 (0) | 2020.12.07 |
자바 스크립트에서 선행 및 후행 쉼표를 어떻게자를 수 있습니까? (0) | 2020.12.06 |
클릭시 입력 텍스트의 기본값 삭제 (0) | 2020.12.06 |
C ++ 전 처리기 : 멤버 변수 목록의 코드 반복 방지 (0) | 2020.12.06 |