MST

星途 面试题库

面试题:Angular服务与依赖注入:作用域及模块相关

在Angular中,服务的作用域与模块之间有什么关系?如何在不同模块间共享服务?如果两个模块对同一个服务有不同的配置需求,该如何处理?
12.3万 热度难度
前端开发Angular

知识考点

AI 面试

面试题答案

一键面试
  1. 服务的作用域与模块之间的关系
    • 在Angular中,服务是单例的,其作用域通常与提供它的模块相关。
    • 当一个服务在模块的providers数组中被提供时,该模块及其所有子模块(如果模块有子模块的话)都可以使用这个服务实例。也就是说,在模块树中,从提供服务的模块开始向下的所有组件都可以注入并使用该服务。
  2. 在不同模块间共享服务
    • 在根模块(通常是AppModule)中提供服务:将服务添加到AppModuleproviders数组中,这样整个应用都可以使用该服务,因为根模块是所有模块的顶级模块。例如:
    @NgModule({
      imports: [],
      declarations: [],
      providers: [MySharedService],
      bootstrap: [AppComponent]
    })
    export class AppModule {}
    
    • 使用forRoot方法:对于一些库模块,通常会提供一个forRoot静态方法。在根模块中调用forRoot方法来提供服务,同时在其他特性模块中导入该模块但不调用forRoot。例如:
    // shared - service.module.ts
    @NgModule({})
    export class SharedServiceModule {
      static forRoot(): ModuleWithProviders<SharedServiceModule> {
        return {
          ngModule: SharedServiceModule,
          providers: [MySharedService]
        };
      }
    }
    // app.module.ts
    @NgModule({
      imports: [SharedServiceModule.forRoot()],
      declarations: [],
      bootstrap: [AppComponent]
    })
    export class AppModule {}
    // feature - module.ts
    @NgModule({
      imports: [SharedServiceModule]
    })
    export class FeatureModule {}
    
  3. 处理两个模块对同一个服务有不同配置需求
    • 使用InjectionToken:定义一个InjectionToken,它可以用来提供不同的配置值。例如:
    import { InjectionToken } from '@angular/core';
    export const MY_SERVICE_CONFIG = new InjectionToken<MyServiceConfig>('my - service - config');
    // 在Module1中
    @NgModule({
      providers: [
        {
          provide: MY_SERVICE_CONFIG,
          useValue: { configValue1: 'value1 - for - module1' }
        },
        MyService
      ]
    })
    export class Module1 {}
    // 在Module2中
    @NgModule({
      providers: [
        {
          provide: MY_SERVICE_CONFIG,
          useValue: { configValue1: 'value1 - for - module2' }
        },
        MyService
      ]
    })
    export class Module2 {}
    // MyService中注入配置
    @Injectable()
    export class MyService {
      constructor(@Inject(MY_SERVICE_CONFIG) private config: MyServiceConfig) {}
    }
    
    • 创建服务的不同变体:可以基于不同的配置需求创建多个类似但有差异的服务类,然后在不同模块中分别提供。例如:
    @Injectable()
    export class MyServiceBase {}
    @Injectable()
    export class MyServiceForModule1 extends MyServiceBase {}
    @Injectable()
    export class MyServiceForModule2 extends MyServiceBase {}
    // 在Module1中
    @NgModule({
      providers: [MyServiceForModule1]
    })
    export class Module1 {}
    // 在Module2中
    @NgModule({
      providers: [MyServiceForModule2]
    })
    export class Module2 {}