我使用Angular:7.2.10,当我尝试使用命令构建生产项目时:
ng b --prod
我遇到错误
ERROR in : Can't resolve all parameters for ApiService in ...
我为带有3个参数的构造函数提供服务:
constructor(api: string, private _http: HttpClient, private httpUtils: HttpUtilsService) {
this.api = `${api}/api`;
}
通过在app.module.ts中定义的工厂实例化:
{
provide: ApiService,
useFactory: apiHost,
deps: [Store, HttpClient, HttpUtilsService]
}
apiHost
export function apiHost(store: Store<RemoteConfig>, http: HttpClient, httpUtils: HttpUtilsService) {
let item: string = localStorage.getItem(environment.apiHost);
//store.pipe(select(backendApiHost), take(1)).subscribe(api => item = api); // Todo not always read val!
//console.log('ss: ' + item);
return new ApiService(item, http, httpUtils);
}
当我使用ng build
时,它可以成功工作。
答案 0 :(得分:1)
通过检查编译器发出的元数据可以隐式解决依赖关系。此元数据是从参数的类型派生的。
在运行时,角度喷射器检查该信息以确定要喷射的依赖项。具体来说,它会为每个对应的参数寻找注册的提供程序。
由于您尚未注册提供程序,该提供程序映射到为类型string
的参数发出的元数据,因此查找失败,并且您收到错误消息。您可以为该类型注册一个提供程序,但鉴于使用的字符串有多广泛,这样做是不明智的。
但是,Angular的依赖项注入工具不限于此隐式解决方案。结合使用Inject
装饰器和InjectionToken
,可以实现您想要的。
api-token.ts
import {InjectionToken} from '@angular/core';
export const apiToken = new InjectionToken('api', {
providedIn: 'root'
});
现在,您可以使用此令牌请求为特定参数解决此依赖性。
data.service.ts
import {InjectionToken, Inject, Injectable} from '@angular/core';
import {apiToken} from './api-token';
@Injectable({providesIn: 'root'})
export class DataService {
constructor(@Inject(apiToken) api: string) {}
}
答案 1 :(得分:0)
Angular找不到api: string
的提供者。实际上,您无需注入ApiService,而是在此处的代码return new ApiService(item, http, httpUtils)
中创建它,因此无需在提供程序中定义它。
答案 2 :(得分:0)
我建议您从构造函数中删除api变量,将其传递给类方法,仅将构造函数用于传递注入。
constructor(public _http: HttpClient) { }
getApi(api: string) {
this._http.get(api).toPromise()
}
然后扩展您的api服务并在参数中传递uri,我建议您也将_http设为公开,api主机也看不到私有http,并且这些键入会导致生成产品失败