简体   繁体   English

Angular导入和导出模块的依赖关系

[英]Dependency in Angular importing and exporting of module

I have a SharedModule that provides and export a service and I would like to import that service in a component of another module by referring to the shared module typescript file instead of the service typescript file. 我有一个提供和导出服务的SharedModule,我想通过引用共享模块typescript文件而不是服务typescript文件在另一个模块的组件中导入该服务。 But the build is failing as somehow the exported service is not detected in the other component. 但是构建失败了,因为在其他组件中未检测到导出的服务。

@NgModule({
  imports: [
    CommonModule
  ],
  declarations: [
      ...
    ],
  providers : [
    LookupService
  ],
  exports : [
    LookupService
  ]
})
export class SharedModule { }

Then it is imported in another feature module 然后将其导入另一个功能模块

  @NgModule({
  imports: [
    CommonModule,
    SharedModule,  
  ],
  declarations: [
    LegalTermComponent
  ],
  providers : [LegalTermService]
})
export class LegalTermModule { }

And in LegalTermComponent which is in LegalTermModule I want to import 在LegalTermComponent中,我想导入LegalTermModule

import { LookupService } from '../shared/shared.module';

This is where build complains .... 这是构建抱怨的地方....

   ERROR in src/app/legal-term/legal-term.component.ts(11,10): error TS2305: Module '".../src/app/shared/shared.module"' has no exported member 'LookupService'.

I cannot figure why it says there is no exported member when clearly the shared module exports it. 我无法理解为什么当共享模块明确地导出它时它没有导出的成员。 Can anyone please tell me the correct way to do this? 有谁能告诉我这样做的正确方法? (the import works fine if I refer directly to lookup.service.ts ) (如果直接引用lookup.service.ts,导入工作正常)

Thanks! 谢谢! Anand 阿南德

Services are singletons with root scope. 服务是具有根范围的单例。 If you want to make sure that the services you provide are singletons at the app level, then you need to import the module with services in the AppModule. 如果您想确保您提供的服务是应用程序级别的单件,那么您需要在AppModule中导入带有服务的模块。 For the FeatureModule, you want to import the SharedModule without any services - otherwise, it can create its own copy of services which overrides the app-level services (ie lazy loaded modules) - that is not likely what you want. 对于FeatureModule,您希望在没有任何服务的情况下导入SharedModule - 否则,它可以创建自己的服务副本来覆盖应用级服务(即延迟加载的模块) - 这可能不是您想要的。

To do this, you should follow the convention of creating two static methods from the shared module: one method returns the module with services, and another method returns the module without services. 为此,您应遵循从共享模块创建两个静态方法的约定:一个方法返回带有服务的模块,另一个方法返回没有服务的模块。

The one without services should only be imported by the FeatureModule. 没有服务的那个只能由FeatureModule导入。 The one with the services should be imported by the AppModule. 具有服务的那个应该由AppModule导入。

FYI, that is why the forRoot (with services) and forChild (without services) convention exists. 仅供参考,这就是为什么存在forRoot (带服务)和forChild (没有服务)约定的原因。

@NgModule({
  imports: [
    CommonModule
  ],
  declarations: [
      ... (shared components)
    ],
  providers : [

  ],
  exports : [
    ... (shared components)
  ]
})
export class SharedModule { 
     // intended to be imported by AppModule
     static forRoot(): ModuleWithProviders {
         return  {
             ngModule: SharedModule, 
             providers: [LookupService]
         }
     }

     // intended to be imported by FeatureModules
     static forChild(): ModuleWithProviders {
         return {
             ngModule: SharedModule, 
             providers: []
         }
     }
}

Feature Modules 功能模块

@NgModule({
  imports: [
    CommonModule,
    SharedModule.forChild(),  //without services
  ],
  declarations: [
    LegalTermComponent
  ],
  providers : [LegalTermService]
})
export class LegalTermModule { }

App Module 应用模块

@NgModule({
  imports: [
    SharedModule.forRoot(), //with services  
  ],
  declarations: [
    ...
  ],
  providers : [
    ...
  ]
})
export class AppModule{ }

To be clear, providers normally have application-wide root scope regardless of which module its provided in. That is because there is no module-scoping mechanism for providers like there is for components. 需要明确的是,提供程序通常具有应用程序范围的根范围,无论其提供哪个模块。这是因为没有像提供组件那样的提供程序的模块范围机制。 The only exception to this are lazy-loaded modules - which introduces their own child-root scope. 唯一的例外是延迟加载的模块 - 它引入了自己的子根范围。

可能是因为您没有导出LookupService类或者没有将它定义为@Injectable()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM