You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 07:45:29