Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
327 views
in Technique[技术] by (71.8m points)

javascript - Getting dependency from Injector manually inside a directive

I am trying to create a generic directive which will take a class type for rule validation and according to the rule in the class the directive will either show or hide an element.

This is my attempt so far.

PLUNKER Demo

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'
  }
}

But I am stuck in 2 places:

  1. I keep getting the error No Provider for AuthService
  2. I do not know how I can get the dependency from Injector using class name as string rather than the type

Any suggestion whether this is the right way to do it or where I am going wrong is highly appreciated.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You need to pass the parent injector like

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

See also Inject service with ReflectiveInjector without specifying all classes in the dependency tree


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...