当我每次注入都需要自己的实例时,Angular 2 DI会使用工厂注入克隆对象的相同实例 [英] Angular 2 DI injects same instance of clonned object with factory when I need own instance for each injection

查看:74
本文介绍了当我每次注入都需要自己的实例时,Angular 2 DI会使用工厂注入克隆对象的相同实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个配置文件,该文件具有数据接口,滚动条的默认配置,注入令牌,以便能够注入此配置以及提供模块的提供程序,该模块包含返回默认配置对象的deepClone的工厂:

I have this Config file which has interface for data, default configuration of scrollbar, injection token to be able to inject this configuration and provider for modules that contains factory which returns deepClone of default config object:

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);
        }
};

这是将提供程序添加到我的模块中的方式:

This is how add provider to my modules:

providers: [
        SCROLLBAR_CONFIG_PROVIDER
    ]

这就是我将其注入到组件的构造函数中的方式:

And that's how I inject it in constructors of my components:

constructor(@Inject(SCROLLBAR_CONFIG) private scrollbarConfig: ScrollbarConfig) {}

所以这个想法是获取滚动条的默认配置,然后扩展每个组件,因此每个组件都有自己的配置。但是由于某种原因,即使我将提供程序与工厂一起使用,注入也会给我相同的实例。我很确定它使默认对象的deepClone成为一个对象,但随后每次注入都返回相同的克隆对象。我也尝试通过创建类而不是注入令牌来做到这一点,但是它的表现却是一样的。

So the idea is to get default config of scrollbar and then extend injected object in each component, so each component has own configuration. But for some reason injection gives me same instance even though I use provider with factory. I am pretty sure it makes a deepClone of default object, but then returns this same clonned object for every injection. I also tried to do it with creating class instead of injection token, but it behaved just the same.

我尝试将console.log()放入工厂函数中并打印出来仅一次,显然这是问题所在,但是我如何强制它真正提供不同的实例?

I tried putting console.log() in factory function and it printed only once so obviously this is the problem, but how can I force it to really provide different instances?

推荐答案

提供者是单个注入器中的单个对象,并且在模块提供者中定义了服务时,该服务属于根注入器(或懒加载模块的子注入器)。

A provider is a singleton within a single injector, and when a service is defined in module providers, it belongs to root injector (or to child injector for lazy-loaded modules).

为了使所有组件都能接收自己的实例,应为这些组件类(而不是模块类)指定提供者

In order for all components to receive their own instances, providers should be specified for these component classes (and not for module class):

@Component({ ..., providers: SCROLLBAR_CONFIG_PROVIDER }) ...

由于该服务从不应该被重用并且是单例,因此它可以是定义为 useValue的类 code>提供商:

Since the service is never supposed to be reused and be a singleton, it can be a class defined as useValue provider instead:

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();
  }
}

这篇关于当我每次注入都需要自己的实例时,Angular 2 DI会使用工厂注入克隆对象的相同实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆