>

나는 각도와 rxjs를 처음 접했습니다. 정적으로 제공되는 텍스트 파일 (로컬에서 서버로)에서 일부 데이터를 가져 오는 angular2 앱을 만들려고합니다. Angular2의 http 공급자와 rxjs의 맵을 사용하여 고정 시간 interval(5000) 를 사용하여 Datamodel에 검색하고 매핑하고 싶습니다. . 제공된 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>


  • 답변 # 1

    @Adam과 @Ploppy가 언급했듯이, Observable.interval ()은 이제 그러한 관찰 가능 객체를 생성하는 선호되는 방식이 아닌deprecated입니다. 이를 수행하는 바람직한 방법은 IntervalObservable 또는 TimerObservable을 사용하는 것입니다. [현재 Typscript 2.5.2, rxjs 5.4.3, Angular 4.0.0에서]

    Angular 2 프레임 워크 에서이 작업을 수행하는 가장 좋은 방법을 보여주기 위해이 답변에 사용법을 추가하고 싶었습니다.

    먼저 서비스 ( 'ng g service MyExample'명령을 통해 각도 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 (HttpClient a la 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);
      }
    }
    
    
    Http (angular5에서 더 이상 사용되지 않음) 대신 HttpClient를 사용하도록 변경하고 rxjs .map () 연산자를 사용하지 않고도 데이터 모델로 응답을 구문 분석 할 수있는 get 메소드를 참고하십시오. 각도 5의 서비스가 변경되는 동안 구성 요소 코드는 변경되지 않습니다.

  • 답변 # 2

    interval 를 사용할 수 있습니다   Observable 의 방법  Angular2 내에서.

    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;
              }):
      }
    }
    
    

    https://plnkr.co/edit/pVMEbbGSzMwSBS4XEXJI?p=preview.를 설명하는 해당 plunkr는 다음과 같습니다.

    이를 바탕으로 HTTP 요청을 연결할 수 있습니다 :

    initializePolling() {
      return Observable
         .interval(60000)
         .flatMap(() => {
           return this.dataService.getData('url'));
         });
    }
    
    

  • 답변 # 3

    최근 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);
      }
    }
    
    

  • 답변 # 4

    Rxjs@5.0.0 (응답시 베타 6)이있는 TypeScript (응답시 1.8.10)/angular2 (응답시 rc1)의 경우 IntervalObservable 를 사용해야합니다.   Observable 를 확장  수업

    import {IntervalObservable} from 'rxjs/observable/IntervalObservable'
    IntervalObservable.create(5000).take(10).map((x) => x + 1)
    
    

  • 답변 # 5

    switchMap 를 통해 쉽게 할 수 있습니다

    Observable.timer(0, 5000)
              .switchMap((t) =>
                this.http.get(...).pipe(
                    catchError(...)
                )
              )
              .subscribe(...)
    
    

  • 이전 sql server - SSDT 게시 프로파일을 재정의합니다 ConnectionString
  • 다음 javascript - 클래스가 열려있는 동안 클래스의 다른 모든 요소를 ​​닫습니다