Angular 2 dynamic dependency injection based on @Input()

前端 未结 4 978
长发绾君心
长发绾君心 2020-12-25 13:18

Suppose I have an Angular 2 component-directive, where I want the injected dependency that the component uses to be determined by an @Input().

I want to write someth

相关标签:
4条回答
  • 2020-12-25 13:52

    In general, same approach is described in Angular2 documentation: InjectorComponent

    @Component({
        providers: [Car, Engine, Tires, heroServiceProvider, Logger]
    })
    export class InjectorComponent {
         car: Car = this.injector.get(Car);
         heroService: HeroService = this.injector.get(HeroService);
         hero: Hero = this.heroService.getHeroes()[0];
    
         constructor(private injector: Injector) { }
    }
    

    You must inject Injector in constructor and list all services in providers property of @Component annotation. Then you can injector.get(type), where type will be resolved from your @Input. As per documentation, Service is not actually injected until you ask for it (.get()).

    0 讨论(0)
  • 2020-12-25 14:04

    There is a service named Inject in @angular/core module. With @Inject you can achieve alternative way of injection. But that can be done only in constructor.

    So you will need to put component's inputs in the inputs array of your @component decorator (do not use @Input decorator inside class) and then inject that input variable in constructor.

    0 讨论(0)
  • 2020-12-25 14:07

    I would like to take Estus Flask answer a step further and create a logic that imports the service rather than having to declare the names as array objects.

    Basically, we just have to pass in the path and name of the service and the rest is almost the same.

    public _dynamicService: any;
    
    dynamicDI(service_path, service_name){
        import(service_path).then(s => {
    
          this._dynamicService = this.injector.get<any>(s['service_name']);
    
        })
    }
    

    Now, you can access the functions inside the dynamicService as follows:

    (Let's assume we have a http observable fn in the service we need)

    this._dynamicService['your_function_name']().subscribe(res=> { console.log(res) } );
    
    0 讨论(0)
  • 2020-12-25 14:08

    It is

    // can be a service also for overriding and testing
    export const trendyServiceMap = {
      serviceA: ServiceA,
      serviceB: ServiceB
    }
    
    constructor(private injector: Injector) {}    
    ...
    ngOnInit() {
        if (trendyServiceMap.hasOwnProperty(this.use)) {
            this.service = this.injector.get<any>(trendyServiceMap[this.use]);
        } else {
            throw new Error(`There's no such thing as '${this.use}'`);
        }
    }
    
    0 讨论(0)
提交回复
热议问题