tipos rotacion razones razon ratios proveedores promedio periodo inventario interpretacion indicadores financieros financieras ejemplos cartera http angular

http - razones - rotacion de cartera



Angular2: muestra el indicador de actividad para cada solicitud HTTP y oculta las vistas hasta que se completa (4)

Sí, necesita manejar eso para cada Vista:

  • Puede tener un servicio para la solicitud http que devolverá un Observable
  • En el Componente tendrá un estado de carga
  • Debe configurar el estado de carga en verdadero antes de solicitar los datos del servidor, y luego configurarlo en falso cuando finalice la búsqueda de datos.
  • En la plantilla use ngIf para ocultar / mostrar la carga o el contenido

    Ej .:

El servicio :

@Injectable() export class DataService { constructor(private http: Http) { } getData() { return this.http.get(''http://jsonplaceholder.typicode.com/posts/2''); } }

El componente :

@Component({ selector: ''my-app'', template : ` <div *ngIf="loading == true" class="loader">Loading..</div> <div *ngIf="loading == false">Content.... a lot of content <br> more content</div>` }) export class App { loading: boolean; constructor(private dataService: DataService) { } ngOnInit() { // Start loading Data from the Server this.loading = true; this.dataService.getData().delay(1500).subscribe( requestData => { // Data loading is Done this.loading = false; console.log(''AppComponent'', requestData); } } }

Un ejemplo de trabajo se puede encontrar aquí: http://plnkr.co/edit/HDEDDLOeiHEDd7VQaev5?p=preview

Soy nuevo en Angular2 y me preguntaba si hay alguna manera de mostrar un indicador de actividad para cada solicitud HTTP y ocultar las vistas hasta que se completen.


Una forma es escribir un interceptor para Anglar2 Http. Al crear su propia instancia de http, puede intercambiar eso cuando está iniciando su aplicación mediante el método de "proporcionar". Una vez hecho esto, se puede crear un servicio PubSub para publicar y suscribirse a estos eventos desde su interceptor Http y emitir antes y después de los eventos en cada solicitud realizada.

Un ejemplo en vivo se puede ver en Plunker

El interceptor:

import {Injectable} from ''angular2/core''; import {HTTP_PROVIDERS, Http, Request, RequestOptionsArgs, Response, XHRBackend, RequestOptions, ConnectionBackend, Headers} from ''angular2/http''; import ''rxjs/Rx''; import {PubSubService} from ''./pubsubService''; @Injectable() export class CustomHttp extends Http { _pubsub: PubSubService constructor(backend: ConnectionBackend, defaultOptions: RequestOptions, pubsub: PubSubService) { super(backend, defaultOptions); this._pubsub = pubsub; } request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> { return this.intercept(super.request(url, options)); } get(url: string, options?: RequestOptionsArgs): Observable<Response> { return this.intercept(super.get(url,options)); } post(url: string, body: string, options?: RequestOptionsArgs): Observable<Response> { return this.intercept(super.post(url, body, this.getRequestOptionArgs(options))); } put(url: string, body: string, options?: RequestOptionsArgs): Observable<Response> { return this.intercept(super.put(url, body, this.getRequestOptionArgs(options))); } delete(url: string, options?: RequestOptionsArgs): Observable<Response> { return this.intercept(super.delete(url, options)); } getRequestOptionArgs(options?: RequestOptionsArgs) : RequestOptionsArgs { if (options == null) { options = new RequestOptions(); } if (options.headers == null) { options.headers = new Headers(); } options.headers.append(''Content-Type'', ''application/json''); return options; } intercept(observable: Observable<Response>): Observable<Response> { this._pubsub.beforeRequest.emit("beforeRequestEvent"); //this will force the call to be made immediately.. observable.subscribe( null, null, () => this._pubsub.afterRequest.emit("afterRequestEvent"); ); return observable } }

Los emisores

import {Subject } from ''rxjs/Subject''; export class RequestEventEmitter extends Subject<String>{ constructor() { super(); } emit(value) { super.next(value); } } export class ResponseEventEmitter extends Subject<String>{ constructor() { super(); } emit(value) { super.next(value); } }

The PubSubService

import {Injectable} from ''angular2/core''; import {RequestEventEmitter, ResponseEventEmitter} from ''./emitter''; @Injectable() export class PubSubService{ beforeRequest:RequestEventEmitter; afterRequest:ResponseEventEmitter; constructor(){ this.beforeRequest = new RequestEventEmitter(); this.afterRequest = new ResponseEventEmitter(); } }

Bootstrapping de la aplicación

//main entry point import {bootstrap} from ''angular2/platform/browser''; import {provide} from ''angular2/core''; import {Http, HTTP_PROVIDERS, XHRBackend, RequestOptions} from ''angular2/http''; import {HelloWorldComponent} from ''./hello_world''; import {CustomHttp} from ''./customhttp''; import {PubSubService} from ''./pubsubService'' bootstrap(HelloWorldComponent, [HTTP_PROVIDERS,PubSubService, provide(Http, { useFactory: (backend: XHRBackend, defaultOptions: RequestOptions, pubsub: PubSubService) => new CustomHttp(backend, defaultOptions, pubsub), deps: [XHRBackend, RequestOptions, PubSubService] }) ]).catch(err => console.error(err));

Ahora en su componente de carga es tan fácil como suscribirse a los eventos y configurar una propiedad para mostrar o no

export class LoaderComponent implements OnInit { showLoader = false; _pubsub:PubSubService; constructor(pubsub: PubSubService) { this._pubsub = pubsub; } ngOnInit() { this._pubsub.beforeRequest.subscribe(data => this.showLoader = true); this._pubsub.afterRequest.subscribe(data => this.showLoader = false); } }

Si bien esto termina siendo un poco más código, si está buscando ser notificado en cada solicitud en su aplicación, esto lo haría. Una cosa a tener en cuenta con el interceptor es que, dado que se realiza una suscripción para cada solicitud, inmediatamente se ejecutarán todas las solicitudes, lo que puede no ser lo que necesita en casos particulares. Una solución para eso es respaldar el Http Angular2 regular y usar el CustomHttp como una segunda opción que se puede inyectar donde sea necesario. Creo que en la mayoría de los casos la suscripción inmediata funcionaría bien. Me encantaría escuchar ejemplos de cuándo no sería así.


Agregue una clase común DAL (capa de acceso a datos) como esta y use esta clase DAL en sus componentes.

Agregue el indicador de carga como un servicio o componente y use sus estilos personalizados para él.

export class DAL { private baseUrl: string = environment.apiBaseUrl; private getConsolidatedPath(path: string) { if (path.charAt(0) === ''/'') { path = path.substr(1); } return `${this.baseUrl}/${path}`; } private callStack = []; private startCall() { this.loadingIndicator.display(true); this.callStack.push(1); } private endCall() { this.callStack.pop(); if (this.callStack.length === 0) { this.loadingIndicator.display(false); } } public get(path: string) { this.startCall(); return this.http.get(this.getConsolidatedPath(path), { headers: this.getHeaders() }) .map(response => response.json()) .catch(e => this.handleError(e)) .finally(() => this.endCall()); } public put(path: string, data: any) { this.startCall(); return this.http.put(this.getConsolidatedPath(path), data, { headers: this.getHeaders() }) .map(response => response.json()) .catch(e => this.handleError(e)) .finally(() => this.endCall()); } public post(path: string, data: any) { this.startCall(); return this.http.post(this.getConsolidatedPath(path), data, { headers: this.getHeaders() }) .map(response => response.json()) .catch(e => this.handleError(e)) .finally(() => this.endCall()); } public delete(path: string, data: any) { this.startCall(); return this.http.delete(this.getConsolidatedPath(path), { body: data, headers: this.getHeaders() }) .map(response => response.json()) .catch(e => this.handleError(e)) .finally(() => this.endCall()); } constructor(public http: Http, public loadingIndicator: LoadingIndicatorService) { } }


Además, @tibbus response

Es mejor configurar el tipo de número "isLoading" y mantenerlo en servicio.

con booleano:

request 1 starts -> spinner on -> request 2 starts -> request 1 ends -> spinner off -> request 2 ends

con número:

request 1 starts -> spinner on -> request 2 starts -> request 1 ends -> request 2 ends -> spinner off

Servicio

@Injectable() export class DataService { constructor(private http: Http) { } private set fetchCounter(v:number) { this._fetchCounter = v; this.isLoadingSource.next(this._fetchCounter > 0) } private get fetchCounter() { return this._fetchCounter }; private _fetchCounter:number = 0; private isLoadingSource = new Subject<boolean>(); public isLoading = this.isLoadingSource.asObservable(); public getData() { this.fetchCounter++; return this.http.get(''http://jsonplaceholder.typicode.com/posts/2'') .map(r => { this.fetchCounter--; return r; }); } }

Solo necesita suscribirse a isLoading desde cualquiera de sus componentes.