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最佳实践的解决思路,步骤很清晰:
- 定义专属注入令牌
在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; // ... 你的其他代码 }
- 修改父类构造函数绑定令牌
用@Inject()装饰器把刚才定义的令牌和apiEndPoint参数绑定起来:
constructor( public http: HttpClient, @Inject(API_ENDPOINT_TOKEN) private apiEndPoint: string, private configService: ConfigService ) { super(null); this.baseUrl = '/api'; }
- 在子类中指定令牌的具体值
修改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
相关产品推荐
相关产品推荐

