我刚刚到Angular2,我想知道是否有任何方式显示每个HTTP请求的活动指标,并隐藏视图直到完成?
一种方法是为Angular2 Http写一个拦截器.通过创建您自己的http实例,您可以通过使用“提供”方法来引导您的应用程序.一旦完成,可以创建一个PubSub服务,以便从Http拦截器发布和订阅这些事件,并在每个请求发生事件之前和之后发出.
Plunker可以看到一个实例
拦截器:
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,options?: RequestOptionsArgs): Observable<Response> { return this.intercept(super.put(url,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 } }
发射器
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); } }
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(); } }
引导应用程序
//main entry point import {bootstrap} from 'angular2/platform/browser'; import {provide} from 'angular2/core'; import {Http,HTTP_PROVIDERS,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,pubsub: PubSubService) => new CustomHttp(backend,defaultOptions,pubsub),deps: [XHRBackend,PubSubService] }) ]).catch(err => console.error(err));
现在在您的加载组件中,它与订阅事件一样简单,并设置属性来显示
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); } }
虽然这最终是一个更多的代码,如果你想要通知你的应用程序中的每个请求,这将做到这一点.有一件事要注意的是拦截器是因为每个请求都会立即执行所有请求的订阅,所有请求都将被执行,这在特定情况下可能不是您需要的.解决方案是支持常规Angular2 Http,并使用CustomHttp作为可以在需要时注入的第二个选项.我认为在大多数情况下,即时订阅将会正常工作.我很乐意听到不会的例子.