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

Angular 4升级至Angular 5执行ng build --prod时出现依赖注入错误

解决Angular 4升级到5后ng build --prod出现的依赖注入错误

嘿,我太懂你升级到Angular 5之后执行ng build --prod碰到的这个糟心问题了!错误提示里的?其实已经点明了关键——Angular的依赖注入(DI)容器没办法解析TouchSystemsService构造函数里的第二个参数。

问题根源

Angular 5默认开启的AOT编译(生产构建必用),对依赖注入的类型检查比Angular 4严格了不止一个档次。你的父类TouchSystemsService构造函数里的第二个参数private apiEndPoint: string是字符串类型,DI容器找不到对应的注入令牌(token)来匹配这个类型,自然不知道该给它传什么值。在Angular 4里靠字面量传递还能蒙混过关,但Angular 5的AOT编译可不会再惯着这种写法。

推荐解决方案:用注入令牌(InjectionToken)明确标识参数

这是最贴合Angular DI最佳实践的解决思路,步骤很清晰:

  1. 定义专属注入令牌
    在TouchSystemsService所在的文件里,先导入InjectionToken并创建一个专属令牌:
import { Injectable, InjectionToken } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, Observable } from 'rxjs';
import { ConfigService } from './your-config-service-path'; // 替换成你的ConfigService实际路径

// 创建注入令牌,用于标识API端点参数
export const API_ENDPOINT_TOKEN = new InjectionToken<string>('ApiEndpoint');

@Injectable()
export class TouchSystemsService extends BehaviorSubject<any> {
  baseUrl: string;
  // ... 你的其他代码
}
  1. 修改父类构造函数绑定令牌
    用@Inject()装饰器把刚才定义的令牌和apiEndPoint参数绑定起来:
constructor(
  public http: HttpClient,
  @Inject(API_ENDPOINT_TOKEN) private apiEndPoint: string,
  private configService: ConfigService
) {
  super(null);
  this.baseUrl = '/api';
}
  1. 在子类中指定令牌的具体值
    修改SizeService的@Injectable装饰器,给令牌指定szie这个字符串值:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { TouchSystemsService, API_ENDPOINT_TOKEN } from './your-touch-service-path';
import { ConfigService } from './your-config-service-path';
import { GridDataResult } from '@progress/kendo-angular-grid'; // 假设你用了Kendo Grid

@Injectable({
  providedIn: 'root',
  providers: [
    { provide: API_ENDPOINT_TOKEN, useValue: 'size' }
  ]
})
export class SizeService extends TouchSystemsService {
  dataResult: GridDataResult;

  constructor(http: HttpClient, configService: ConfigService) {
    super(http, configService); // 这里不用再传'size',令牌会自动注入对应值
  }

  public read(id: number): Observable<GridDataResult> {
    return this.fetchById(id);
  }
}

备选方案:从ConfigService统一获取端点值

如果你的ConfigService本来就负责管理API端点配置,也可以把apiEndPoint的获取逻辑移到父类里,省去单独注入参数的麻烦:

// 修改TouchSystemsService构造函数
constructor(public http: HttpClient, private configService: ConfigService) {
  super(null);
  this.baseUrl = '/api';
  // 假设ConfigService有getApiEndpoint方法,返回对应端点字符串
  this.apiEndPoint = this.configService.getApiEndpoint();
}

// 修改SizeService的super调用
constructor(http: HttpClient, configService: ConfigService) {
  super(http, configService);
}

这种方法适合所有子类的API端点都能统一从配置中心获取的场景。

内容的提问来源于stack exchange,提问作者Shariq

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:13:31