在指令中手动从注入器获取依赖

Getting dependency from Injector manually inside a directive

本文关键字:注入器 获取 依赖 指令      更新时间:2023-09-26

我正在尝试创建一个通用指令,它将采用类类型进行规则验证,并根据类中的规则,该指令将显示或隐藏元素。

这是我目前为止的尝试。

恰好演示

myIf-Directive.ts

@Directive({
  selector: '[myIf]'
})
export class MyIfDirective {
  constructor(private _viewContainer: ViewContainerRef,
    private _template: TemplateRef<Object>) 
  { }
  @Input() set myIf(rule: string) {
    //rule class type will come as string
    //how can I use string token to get dependency from injector?
    //currently harcoded
    //will the injector create new instance or pass on instance from parent?
    let injector = ReflectiveInjector.resolveAndCreate([AdminOnly]);
    let adminOnly : IRule = injector.get(AdminOnly);
    let show = adminOnly.shouldShowElement();
    show ? this.showItem() : this.hideItem();
  }
  private showItem() {
    this._viewContainer.createEmbeddedView(this._template);
  }
  private hideItem() {
    this._viewContainer.clear();
  }
}


app-component.ts

@Component({
  selector: 'my-app',
  template: `
    <div *myIf="'AdminOnly'">
      <h2>Hello {{name}}</h2>
    </div>
  `,
})
export class App {
  name:string;
  constructor() {
    this.name = 'Angular2'
  }
}

但我被困在两个地方:

  1. 我一直得到错误No Provider for AuthService
  2. 我不知道如何从注入器获得依赖使用类名作为字符串而不是类型

任何建议是否这是正确的方式去做,或者我错了,是非常感谢。

你需要像

这样传递父注入器
export class MyIfDirective {
  constructor(private injector:Injector, private _viewContainer: ViewContainerRef,
    private _template: TemplateRef<Object>) 
  { }
  @Input() set myIf(rule: string) {
    let resolvedProviders = ReflectiveInjector.resolve([AdminOnly]);
    let childInjector = ReflectiveInjector.fromResolvedProviders(resolvedProviders, this.injector);
    let adminOnly : IRule = childInjector.get(AdminOnly);
    let show = adminOnly.shouldShowElement();
    show ? this.showItem() : this.hideItem();
  }
  private showItem() {
    this._viewContainer.createEmbeddedView(this._template);
  }
  private hideItem() {
    this._viewContainer.clear();
  }
}

参见用ReflectiveInjector注入服务,而不指定依赖树中的所有类

只需更新Angular 10+版本:

  • 从您的服务:
  @Injectable({
    providedIn: 'any'
  })
  export class AdminOnly { ... }
  • 在指令或纯函数中,…:
 import { Injector } from '@angular/core';
 ...
 const injector: Injector = Injector.create({
   providers: [{provide: AdminOnly, deps: []}]
 });
 const adminOnly: AdminOnly = injector.get(AdminOnly);
 let show = adminOnly.shouldShowElement();
 ...

看到更多