Angular: 多个模块使用的服务放在哪里

Angular: where do I put services used by multiple modules

我刚开始使用 angular 框架的功能模块 + 延迟加载的路由部分,并且在适应这些细微差别时遇到了一些麻烦。不时出现的一件事是如何存储服务和接口——它们是否应该只放在使用它们的模块的提供程序数组中?或者应该将某种主要服务模块注入到根模块中?

我从各种教程中了解到,服务和接口不应该放在核心模块或共享模块中。

我之前在做什么:

//service.module.ts
@NgModule({
    imports: [],
    exports: [],
    declarations: [],
    providers: [],
})
export class ServicesModule {
    static forRoot(): ModuleWithProviders<ServicesModule> {
        return {
            ngModule: ServicesModule,
            providers: [
              all the services
              provided in our application
            ]
        }
    }
}
// then in app.module.ts
imports: [
    ServicesModule.forRoot(),
]

所以我的选择是

  1. 保留原样设置,在应用程序文件夹中有一个名为 'services' 的集合目录,并在需要服务的组件中使用构造函数 DI。同样使用 models/interfaces,从名为 'models'.
  2. 的目录中导入它们
  3. 将服务移动到需要它们的模块中,并且只在 ServicesModule 中提供共享服务,有助于延迟加载模块。

我想 different/easier 问题是,如果我将所有服务移回 我的 app.module,这会简化事情吗?似乎违反直觉。

如果您将所有这些都放在一个服务模块中并将其导入 AppModule,那么它的行为与 Injectable({ providedIn: 'root' }) 相同。如果确实需要全局可访问,将服务标记为 providedIn: 'root' 并没有错,而且 Angular 仍然会以某种方式延迟加载,如果没有任何东西注入它。最主要的是只有一个服务实例被创建并在注入它的所有东西之间共享(除非你在另一个 module/component 的 providers 数组中重新提供它)。

对于某些事情,这种行为是可取的。例如,如果您有一项用户服务提供有关当前登录用户的数据,那么该服务很可能是一种无处不在且只需要创建一个实例的服务。所以在那种情况下,providedIn: 'root' 或在 AppModule 中提供它是有道理的。

相反,如果您有一项为 table 组件提供 table 数据的服务,那么您可能希望在组件级别提供该服务,以便 table 的每个单独实例=40=] 可以访问自己的数据。如果您以根目录提供此服务,那么每个 table 将共享相同的数据。

通常我所做的是要么在需要的地方 component/module 提供服务,要么在整个应用程序中需要单例时 providedIn: 'root' 提供服务。

您还可以创建小的“原子”模块,其中该模块提供一种服务,然后在需要的任何地方导入该小模块以允许延迟加载。

例如:

@NgModule({
    providers: [TestService]
})
export class TestModule { }

然后任何具有 component/directive/service/etc 的模块需要注入该服务,您可以将 TestModule 添加到包含 component/directive/service/etc 的模块的 imports 数组中。

constructor(private testService: TestService) { }
@NgModule({
    imports: [TestModule]
})
export class ModuleWithComponentThatNeedsTestService { }

我的另一个想法是为我的任何网站定义一个通用服务 api 组件正在交互。就像在反应中完成的那样,使用钩子和 useContext:

useFirestore.js
useStorage.js
useAnalytics.js

我不确定这是否好,因为我看到其他人编写的大多数 angular src 代码都具有始终特定于他们正在访问的数据库集合或文档的服务。我现在正在考虑,这是否是个好主意。缺点是这将是一个巨大的服务,在我的应用程序中随处调用,这当然没有吸引力。

export class FirestoreService {

  collection : AngularFirestoreCollection<any>;

  constructor(
    collectionName : string,
    collectionMetadata : { },
    private afs : AngularFirestore
   ) {
      this.collection = this.afs.collection(collection_name)

 }

  create( new_object : { }) { }
  update( new_object: {} ) { }
  delete( ) { } 
  filter,
  search,
  etc...
  
}