简体   繁体   English

角 | 将服务注入装饰器

[英]Angular | Inject service into decorator

I am trying to inject a service into a decorator function in which I am creating, this is so I can get the contents that are stored inside of variables.我正在尝试将服务注入到我正在创建的装饰器函数中,这样我就可以获得存储在变量中的内容。

I currently have a basic decorator setup.我目前有一个基本的装饰器设置。

export function canEdit(editName: string, service: Service) {
      return function (constructor: any) {
          console.log(constructor);
      }
}

Where I am using this it is asking me for the second parameter, which obviously needs to be dependency injected.在我使用它的地方,它要求我输入第二个参数,这显然需要注入依赖项。

I have also tried the @Inject(Service) which isn't allowed within functions.我还尝试了函数中不允许的@Inject(Service)

Is there a way that I can do this?有没有办法我可以做到这一点?

Or is it possible to get the parent classes variables within the decorator?或者是否可以在装饰器中获取父类变量?

Decorators are a TypeScript feature that work outside of Angular's dependency injection system.装饰器是在 Angular 的依赖注入系统之外工作的 TypeScript 功能。

The only solution that I know of is to create a special service that will expose dependencies to the decorator.我知道的唯一解决方案是创建一个特殊服务,将依赖项暴露给装饰器。

@Injectable()
export class DecoratorService {
     private static service: Service | undefined = undefined;
     public constructor(service: Service) {
         DecoratorService.service = service;
     }
     public static getService(): Service {
         if(!DecoratorService.service) {
             throw new Error('DecoratorService not initialized');
         }
         return DecoratorService.service;
     }
}

You can now access the injected service via the above class.您现在可以通过上述类访问注入的服务。

export function canEdit(editName: string) {
      return function (constructor: any) {
          const service = DecoratorService.getService();
          // ^^^ access dependency here
          console.log(constructor);
      }
}

The above will not work unless something in the Angular application depends upon DecoratorService because Angular creates instances when they are needed.除非 Angular 应用程序中的某些内容依赖于DecoratorService ,否则上述方法将不起作用,因为 Angular 在需要时会创建实例。 So you can inject it into a module to force it to be initialized.因此,您可以将其注入到模块中以强制对其进行初始化。

@NgModule({
    provides: [
        DecoratorService
    ]
})
export class MainModule {
    public constructor(service: DecoratorService) {
                      // ^^^ forces an instance to be created
    }
}

I know I'm late to the party, but, there's another alternative to access a Service in a Decorator.我知道我迟到了,但是,在装饰器中访问服务还有另一种选择。

Expose Angular's Injector in the module where the necessary services are required:在需要必要服务的模块中公开 Angular 的 Injector:

@NgModule({
  declarations: [],
  imports: [],
  providers: [SomeService]
})
export class SharedModule {
  static injector: Injector;

  constructor(injector: Injector) {
    SharedModule.injector = injector;
  }
}

Get the service from inside the Decorator via the Module injector property:通过 Module injector 属性从装饰器内部获取服务:

export const MyDecorator = (): any => {

  return (target: object, key: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor => {
    const originalMethod = descriptor.value;

    descriptor.value = function(...args: any[]): any {
      // access the service
      const service = SharedModule.injector.get<SomeService>(SomeService);

      // (...)
    };

    return descriptor;
  };
};

Angular Dependancy injection works only within a component class or an angular service which is depending on another service. Angular Dependancy 注入仅适用于依赖于另一个服务的组件类或 Angular 服务。

The consumer of the dependency which is the angular component, declares what it requires in its constructor, and lets the framework provide them.依赖的消费者是角度组件,在其构造函数中声明它需要什么,并让框架提供它们。

for more on dependency injection please refere to the officiel angular documentation:有关依赖注入的更多信息,请参阅官方 Angular 文档:

Dependency Injection in action依赖注入在行动

https://next.angular.io/guide/dependency-injection-in-actionhttps://next.angular.io/guide/dependency-injection-in-action

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM