Angular 7:如何在Service.ts中正确初始化变量实现代码复用
Angular Service变量初始化问题解决指南
核心问题分析
构造函数执行时机过早,此时AuthService中的user/ampUser可能还未完成初始化(比如用户信息是通过异步请求、本地存储读取等延迟加载的),导致你尝试访问this.authorized.user时出现异常,甚至误判this.authorized为undefined。而在getCollections方法中调用时,用户信息已经加载完成,所以能正常工作。
解决方案
方案1:使用Getter动态获取(贴合DRY原则)
将urlBase和token改为动态Getter,每次使用时自动获取最新值,避免提前初始化的问题:
export class CollectionsService { constructor( private authorized: AuthService, private http: Http, private httpHelper: HttpHelperService ) {} // 动态生成基础URL private get urlBase(): string { return `/app/${this.authorized.ampUser.appdomainid}`; } // 动态获取token private get token(): string { return this.authorized.ampUser.token; } getCollections(): Observable<any> { return this.http .get( `${this.urlBase}/collections`, this.httpHelper.getRequestOptions(this.token) ) .pipe( map((response) => <any>response.json()), map((response) => response.Items), catchError((err) => throwError(err.json())) ); } }
方案2:监听用户状态变化
如果用户信息是异步加载的,可订阅AuthService的用户状态流,在信息就绪后再初始化变量:
import { Subscription } from 'rxjs'; import { OnDestroy } from '@angular/core'; export class CollectionsService implements OnDestroy { private urlBase: string; private token: string; private userSubscription: Subscription; constructor( private authorized: AuthService, private http: Http, private httpHelper: HttpHelperService ) { // 监听用户信息更新 this.userSubscription = this.authorized.user$.subscribe(user => { if (user) { this.urlBase = `/app/${user.appdomainid}`; this.token = user.token; } }); } // 销毁组件时取消订阅,避免内存泄漏 ngOnDestroy(): void { this.userSubscription?.unsubscribe(); } getCollections(): Observable<any> { // 避免空值调用 if (!this.urlBase || !this.token) { return throwError('用户信息未就绪'); } return this.http .get( `${this.urlBase}/collections`, this.httpHelper.getRequestOptions(this.token) ) .pipe( map((response) => <any>response.json()), map((response) => response.Items), catchError((err) => throwError(err.json())) ); } }
方案3:封装通用逻辑到HttpHelper
将基础URL拼接逻辑迁移到HttpHelperService,进一步复用代码:
// HttpHelperService.ts export class HttpHelperService { constructor(private authorized: AuthService) {} getBaseUrl(): string { return `/app/${this.authorized.ampUser.appdomainid}`; } getRequestOptions(token?: string): RequestOptions { const authToken = token || this.authorized.ampUser.token; return new RequestOptions({ headers: new Headers({ 'Authorization': `Bearer ${authToken}` }) }); } } // CollectionsService.ts export class CollectionsService { constructor( private http: Http, private httpHelper: HttpHelperService ) {} getCollections(): Observable<any> { return this.http .get( `${this.httpHelper.getBaseUrl()}/collections`, this.httpHelper.getRequestOptions() ) .pipe( map((response) => <any>response.json()), map((response) => response.Items), catchError((err) => throwError(err.json())) ); } }
内容的提问来源于stack exchange,提问作者Kirk Ross
相关产品推荐
相关产品推荐

