不久前,我们开始创建内部NPM包,其中包含角度组件,因此我们可以在不同站点之间重用我们常用的角度组件。通过我们正在做的一些新工作,我们正在尝试支持AOT编译以及使NPM包中的组件与角度2.x和4.x兼容。我们有一些配置需要传递到npm包/库(api keys / urls,environment等),所以我想让实现站点提供一个配置对象,可以将其注入需要这些值的组件中。我在让提供商与AOT合作时遇到问题。到目前为止,我能够使用它的唯一方法是使用显式的字符串标记,但这在我看来并不理想。
工作:
在消费的AOT网站上:
import { environment } from './../environments/environment';
@NgModule({
declarations: [
...
],
imports: [
...
],
providers: [
{
provide: 'ConfigToken',
useValue: environment
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
在库组件中:
constructor(@Inject('ConfigToken') private config: Configuration) { }
从库导出的接口:
export interface Configuration {
someValue: string;
someOtherValue: string;
}
我试过了:
OpaqueToken
导出一个类以用作令牌
使用这两种策略时,我最终会收到错误ERROR in Can't resolve all parameters for SomeComponent in C:/Development/path/to/bundle
答案 0 :(得分:1)
好吧,我最终找到了自己问题的答案......问题在于使用接口作为注入值的类型。我正在查看生成的java脚本并注意到这一点:
SomeComponent.ctorParameters = function () { return [
{ type: undefined, decorators: [{ type: _angular_core.Inject, args: [MyProviderToken,] },] },
]; };
一旦我将类型更改为类而不是接口,类型就不再是未定义的,而angular能够注入使用应用程序提供的值。
答案 1 :(得分:0)
您可以在注入类上使用'useValue'选项在运行时重新定义它。这就是我为我的应用程序提供配置的方式。只需创建一个简单的可注入占位符,如
import { Injectable } from '@angular/core'
@Injectable() export class MyAppConfig {}
然后在您的模块中,您可以从任何文件导入一些常量。让我们说const看起来像这样
export const MY_APP_CONFIG = {
configOption1 = 'test1';
configOption2 = 123;
}
现在在您的模块中,您可以导入可注入类和常量
import { MyAppConfig } from './wherever/it/is'
import { MY_APP_CONFIG } from './wherever/it/is'
然后在提供商
中 providers: [
{
provide: MyAppConfig,
useValue: MY_APP_CONFiG
}
],
使用InjectionToken https://angular.io/api/core/InjectionToken
可能有更好的方法但这更简单,对我有用。根据我的理解,这种方法的缺点是它不会阻止命名空间冲突。
编辑 -
关于如何在组件中使用它......
导入injectable配置类
import { MyAppConfig } from './wherever'
然后在构造函数
中constructor(private config: MyAppConfig) {
console.log(config);
}
您将看到它打印您分配给它的const值而不是空对象。