在Angular中向父类注入依赖服务

6

我有一个类 parentchildchild 类继承自 parent。 我需要将可注入的类 service 注入到 parent 中,因为所有的 child 都会使用它。 我该怎么做?

3个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
9
你可以使用Injector类注入任何父级服务或类。你需要从子级注入Injector类,并通过super(injector)将其传递给父级,以便父级可以从来自子级的注入器中注入可重用的服务。

父类:

export class BaseComponent implements OnInit {

    protected myService: MyService

    constructor(injector: Injector) {
        this.myService = injector.get(MyService)
    }

    ngOnInit() {
        console.log('ngOnInit from Base');
    }
}

子类:

export class AppComponent extends BaseComponent {

  constructor(injector: Injector) {
    super(injector)
  }

  ngOnInit() {
    super.ngOnInit()
    this.myService.getUsers()
  }
}

使用这种方法,您不需要从子级注入每个服务以逐个传递到父级,上述方法更有效地从父级注入。


这听起来像是被接受的答案,但多了一些步骤。将注入器传递而不仅仅是传递我的服务的注入实例,我会得到任何优势吗? - Nicu Surdu
@NicuSurdu 这种方法更加灵活,因为添加新的依赖项不需要更改两个构造函数。在我看来,这里的主要缺点是违反了显式依赖原则 - Kirk Larkin

7
您无法将依赖注入到父类中,因为Angular不会为您实例化它。它创建的是子类的实例,这有效地初始化了父类(虽然类只是语法糖,但对于本文讨论而言,这种表述还是比较恰当的)。 一种常见的解决方案是,将子类设置为可注入的,并使用super传递依赖项。例如:
class Parent {
    constructor(protected someService: SomeService) { }
}

@Injectable()
class Child extends Parent {
    constructor(someService: SomeService) {
        super(someService);
    }
}
如果Parent实际上不需要该依赖项,最好在子类上使用@Injectable(),这些子类可以有自己私有的依赖项引用。

这个答案更好,因为代码示例使用了Angular的约定,在父类和子类的构造函数参数中创建了类型为SomeService的受保护的someService。 - MichaelHuelsen

1
如果您想避免在子类和父类之间重复传递注入器或被注入实例,您可以使用这个解决方案。

创建一个只有一个静态属性的类:

export class AppModuleServices{
    static injector: Injector;
}
然后在创建服务的模块中设置注入器的值:
import {Injector, NgModule} from '@angular/core';    
@NgModule({
      providers: MyService
    })
    export class AppModule {
      constructor(private injector: Injector) {
        AppModuleServices.injector = this.injector;
      }
    }
只要模块已经被实例化,您现在可以在任何类中使用静态注入器,并检索模块的任何服务:
export class MyParentClass {
  private myService: MyService;

  constructor () {
     this.myService = AppModuleServices.get<MyService>(MyService);
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,