Angular 4如何等待httpclient完成
发布时间:2020-12-17 17:43:25 所属栏目:安全 来源:网络整理
导读:在我的应用程序中,我有从自定义基本服务继承的服务(正在调用其余服务),该服务定义了在所有其他服务中使用的公共方法和属性.其中一个参数是我的休息服务的基本URL,它在环境下使用变量.但是现在需要使这个url来自配置文件.因此,我必须使用httpclient来获取它,
在我的应用程序中,我有从自定义基本服务继承的服务(正在调用其余服务),该服务定义了在所有其他服务中使用的公共方法和属性.其中一个参数是我的休息服务的基本URL,它在环境下使用变量.但是现在需要使这个url来自配置文件.因此,我必须使用httpclient来获取它,这提出了一个问题,现在当实际服务尝试使用基本URL时,它还没有解决.有没有办法等待电话结算?
我的代码看起来像: 基service.service.ts: export class BaseService{ protected apiUrlBase: string; constructor(protected _http: HttpClient) { // some logic this.getConfigData() .subscribe( x => { this.apiUrlBase = x.apiUrlBase; } ); } getConfigData(): Observable<any> { return this._http.get( '../../assets/config.json' ) .do(x => { }) .catch(error => { alert('Unable to read configuration file:' + JSON.stringify(error)); return Observable.throw(error); }); } } 一些-data.service.ts: @Injectable() export class TestService extends BaseApiService { private get _someDataServiceUrl(): string { return this.apiUrlBase + '/api/v1/somedata'; } constructor(_http: HttpClient) { super(_http); } getSomeData(): Observable<ISomeData[]> { return this._http.get<ISomeData[]>(this._someDataServiceUrl) .do(this.handleSuccessResponse) .catch(this.handleErrorResponse); } } 有关我如何等待我的服务直到apiUrl得到解决的任何建议,或者我应该怎样做才能使用我的baseservice以及使用子服务所依赖的数据直到他们使用它? 解决方法
快速而肮脏的是使URL基础本身是可观察的,并确保服务中的任何内容都可以继续,直到它给出一个值:
export class BaseService{ protected apiUrlBase: BehaviorSubject<string> = new BehaviorSubject<string>(null); protected apiUrlBase$: Observable<string> = this.apiUrlBase.filter(b => !!b).take(1); constructor(protected _http: HttpClient) { // some logic this.getConfigData() .subscribe( x => { this.apiUrlBase.next(x.apiUrlBase); } ); } getConfigData(): Observable<any> { return this._http.get( '../../assets/config.json' ) .do(x => { }) .catch(error => { alert('Unable to read configuration file:' + JSON.stringify(error)); return Observable.throw(error); }); } } @Injectable() export class TestService extends BaseApiService { private _someDataServiceUrl(apiUrlBase): string { return apiUrlBase + '/api/v1/somedata'; } constructor(_http: HttpClient) { super(_http); } getSomeData(): Observable<ISomeData[]> { return this.apiUrlBase$.switchMap(apiUrlBase => this._http.get<ISomeData[]>(this._someDataServiceUrl(apiUrlBase)) .do(this.handleSuccessResponse) .catch(this.handleErrorResponse)); } } 但这显然非常难看.更好的解决方案是通过为应用程序创建应用程序初始化程序提供程序,确保此基本服务在应用程序中的任何其他内容之前加载和解析: import { Injectable,APP_INITIALIZER } from '@angular/core'; @Injectable() export class BaseService{ protected apiUrlBase: string; constructor(protected _http: HttpClient) { } getConfigData(): Observable<any> { return this._http.get( '../../assets/config.json' ) .do(x => { }) .catch(error => { alert('Unable to read configuration file:' + JSON.stringify(error)); return Observable.throw(error); }); } public load() { return new Promise((resolve,reject) => { this.getConfigData() .subscribe( x => { this.apiUrlBase = x.apiUrlBase; resolve(true); },err => resolve(err) ); }); } } export function BaseServiceInitFactory(baseService: BaseService) { return () => baseService.load(); } export const BaseServiceInitProvider = { provide: APP_INITIALIZER,useFactory: BaseServiceInitFactory,deps: [BaseService],multi: true } 然后将BaseServiceInitProvider放在您的应用程序模块提供程序中的BaseService之后. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |