Angular: provider 和 serivce 的关系

129 阅读2分钟

当然可以!这个问题的核心是理解 依赖注入(Dependency Injection,DI)服务提供者(Providers) 在 Angular 中的作用。

为什么要在 providers 中指定服务名称?

  1. 依赖注入系统: Angular 使用依赖注入系统来管理服务的生命周期和实例化过程。服务是通过 Angular 的依赖注入系统提供的,并且它们在不同的作用域(例如:应用、模块、组件)中可以有不同的实例。

  2. 作用域和实例化

    • 如果你没有在 providers 中声明服务,Angular 会查找全局范围内的提供者,通常在 @NgModule 中配置的 providers 数组中。
    • 如果你在组件中 providers: [MyService],你就是告诉 Angular:在该组件内创建和提供一个新的 MyService 实例。这意味着每个实例(每个组件的实例)都会有自己的 MyService 实例。
  3. 组件和服务的实例化

    • 通过在构造函数中注入 MyService(如 constructor(private myService: MyService)),Angular 会自动将之前在 providers 中声明的 MyService 实例传递给 myService 属性。
    • 但如果你没有在 providers 中指定 MyService,Angular 就会使用默认的、全局的提供方式(比如在根模块中配置)。如果你需要组件特定的服务实例,就必须在该组件的 providers 数组中明确声明。

举个例子:

export class MyService {
   private a=0;
   constructor() { }

   public testAaa() {
       this.a++;
       console.log(this.a);
   }

}

  1. 全局提供服务: 如果你在 AppModuleproviders 中声明了服务(providedIn: 'root'providers: [MyService]),Angular 会全局管理这个服务,整个应用中只有一个 MyService 实例。

    @NgModule({
      providers: [MyService]
    })
    export class AppModule {}
    

    如果两个组件都调用MyService.testAaa()时的结果:

    1
    2
    
  2. 组件级别提供服务: 如果你在某个组件中提供服务(providers: [MyService]),那么每次该组件创建时,都会为它提供一个新的 MyService 实例。这样就能确保该组件有自己的服务实例,而不是共享全局实例。

    @Component({
      selector: 'app-my-component',
      providers: [MyService],  // 组件级别提供服务
      template: `<div>{{ myService.getData() }}</div>`
    })
    export class MyComponent {
      constructor(private myService: MyService) {}
    }
    

    如果两个组件都调用MyService.testAaa()时的结果:

    1
    1
    

    代表两个组件各自生成了自己的MyService实例,而不是共用一个 这意味着即使 MyService 在根模块中有提供,组件内部也可以独立提供它自己的实例,防止组件间的服务实例共享。

总结:

  • providers 数组的作用是告诉 Angular 如何创建和提供该组件或模块所依赖的服务实例。如果在组件中提供服务,它将创建一个新的实例;如果不提供,则会使用全局提供的服务实例。
  • 构造函数中的注入:通过 constructor(private myService: MyService),你只是声明了你需要的服务,Angular 会自动为你注入已提供的实例。