我有这个Config文件,它有数据接口,滚动条的默认配置,能够注入此配置的注入令牌以及包含返回默认配置对象的deepClone的工厂的模块的提供者:
export interface ScrollbarConfig {
name: string;
class: string;
options: MCustomScrollbar.CustomScrollbarOptions;
}
export const SCROLLBAR_CONFIG = new InjectionToken<ScrollbarConfig>('scrollbar.config');`
export const SCROLLBAR_CONFIG_DEFAULT: ScrollbarConfig = { ... }
export const SCROLLBAR_CONFIG_PROVIDER = {
provide: SCROLLBAR_CONFIG,
useFactory: () => {
return _.cloneDeep(SCROLLBAR_CONFIG_DEFAULT);
}
};
这是我的模块添加提供程序的方法:
providers: [
SCROLLBAR_CONFIG_PROVIDER
]
这就是我在组件的构造函数中注入它的方式:
constructor(@Inject(SCROLLBAR_CONFIG) private scrollbarConfig: ScrollbarConfig) {}
因此,我们的想法是获取滚动条的默认配置,然后在每个组件中扩展注入的对象,因此每个组件都有自己的配置。但由于某种原因注射给我同样的实例,即使我使用提供者与工厂。我很确定它会生成一个默认对象的deepClone,但是每次注入都会返回相同的clonned对象。我也尝试过创建类而不是注入令牌,但它表现得一样。
我尝试将console.log()放在工厂函数中,它只打印一次,所以很明显这是问题所在,但我怎么能强制它真正提供不同的实例呢?
答案 0 :(得分:1)
提供程序是单个注入器中的单例,当在模块providers
中定义服务时,它属于根注入器(或延迟加载模块的子注入器)。
为了让所有组件都能接收自己的实例,应该为这些组件类指定providers
(而不是模块类):
@Component({ ..., providers: SCROLLBAR_CONFIG_PROVIDER }) ...
由于服务永远不应该被重用并且是单例,因此它可以是定义为useValue
提供者的类:
export class ScrollbarConfig {
name: string = ...;
class: string = ...;
// or
// constructor() {
// return _.cloneDeep(SCROLLBAR_CONFIG_DEFAULT)
// }
}
@Module({ ..., providers: { provide: ScrollbarConfig, useValue: ScrollbarConfig }) ...
@Component(...)
class SomeComponent {
scrollbarConfig: ScrollbarConfig;
constructor(@Inject(ScrollbarConfig) ScrollbarConfig: typeof ScrollbarConfig) {
this.scrollbarConfig = new ScrollbarConfig();
}
}