page navigationend change angular rxjs5

navigationend - Angular2+http en un intervalo



router events subscribe angular 4 (6)

Soy bastante nuevo en angular y rxjs. Estoy tratando de crear una aplicación angular2 que obtenga algunos datos del archivo de texto servido estáticamente (Localmente en el servidor), que me gustaría recuperar y asignar a Datamodel usando el proveedor http de Angular2 y el mapa de rxjs en un interval(5000) tiempo fijo interval(5000) . Para reflejar cualquier cambio en el archivo txt servido.

Con rxjs 4.x, sé que puede usar Observable.interval(5000) para hacer el trabajo, pero no parece existir en rxjs 5. Mi solución actual actualmente actualiza toda la aplicación usando <meta http-equiv="refresh" content="5" > Que vuelve a cargar toda la página y, por lo tanto, vuelve a cargar los datos.

Entonces, lo que realmente me gustaría es alguna forma de hacer esto trabajando con observables, tal vez para verificar si se han producido cambios. o simplemente para recargar los datos nuevamente.

Cualquier ayuda u otra / mejor manera será muy apreciada.

Lo que tengo hasta ahora:

@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") ); } }

Dependencias: 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" }

importaciones 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>


Descargo de responsabilidad: originalmente era una edición para otra respuesta, pero contiene demasiados cambios.

Esto se puede hacer fácilmente a través de switchMap :

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

O en la sintaxis de RxJS 6 :

import { timer } from ''rxjs''; import { switchMap } from ''rxjs/operators''; timer(0, 5000) // repeats every 5 seconds .pipe(switchMap(() => this.http.get(...).pipe(...)) .subscribe(...);

Incluso puede usar un interval lugar de un timer :

import { interval } from ''rxjs''; import { switchMap } from ''rxjs/operators''; interval(5000) // repeats every 5 seconds .pipe(switchMap(() => this.http.get(...).pipe(...)) .subscribe(...);


Como @Adam y @Ploppy mencionaron, el Observable.interval () ahora está en desuso, no es la forma preferida de crear un observable. La forma preferida de hacerlo es a través de IntervalObservable o TimerObservable. [actualmente en Typscript 2.5.2, rxjs 5.4.3, Angular 4.0.0]

Quería agregar algo de uso a esta respuesta para demostrar lo que encontré la mejor manera de hacerlo en el marco de Angular 2.

Primero su servicio (creado en cli angular a través del comando ''ng g service MyExample "). Suponiendo que el servicio es RESTful (la solicitud http get devuelve un 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()); } }

*** ver actualizaciones inferiores al servicio para Angular 5 ***

Ahora su código de componente (''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 } }

=== editar ===

Se actualizó el código ts del componente para consolidar las suscripciones a través de un 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 } }

=== editar ===

my-example-service.ts (usando el 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); } }

Observe el cambio para usar HttpClient en lugar de Http (en desuso en angular5) y el método get que permite analizar la respuesta en nuestro modelo de datos sin tener que emplear el operador rxjs .map (). Mientras el servicio cambia para angular 5, el código del componente permanece sin cambios.


Creo que esta respuesta ya no es válida debido a los cambios recientes de rxjs / observable. Ahora debe usar 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); } }


Esto se puede hacer fácilmente a través de switchMap

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


Para TypeScript (1.8.10 en el momento de la respuesta) / angular2 (rc1 en el momento de la respuesta) con [email protected] (beta.6 en el momento de la respuesta) debe usar IntervalObservable que amplía la clase Observable

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


Puede usar el método de interval de Observable dentro de 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; }): } }

Aquí está el plunkr correspondiente que describe esto: https://plnkr.co/edit/pVMEbbGSzMwSBS4XEXJI?p=preview .

En base a esto, puede conectar su solicitud HTTP:

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