【问题标题】:Dependency in Angular importing and exporting of moduleAngular导入和导出模块的依赖关系
【发布时间】:2017-12-14 20:40:11
【问题描述】:

我有一个提供和导出服务的 SharedModule,我想通过引用共享模块打字稿文件而不​​是服务打字稿文件来将该服务导入另一个模块的组件中。但是构建失败了,因为在其他组件中未检测到导出的服务。

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

然后导入到另一个功能模块中

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

在 LegalTermComponent 中我想导入 LegalTermModule

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

这是构建抱怨的地方......

   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'.

当共享模块明确导出它时,我不明白为什么它说没有导出成员。谁能告诉我这样做的正确方法? (如果我直接参考 lookup.service.ts 导入工作正常)

谢谢! 阿南德

【问题讨论】:

  • legalTermComponent 在哪里? sharedModule?
  • 你能发布 LookupService 类吗?

标签: angular


【解决方案1】:

服务是具有根范围的单例。如果您想确保您提供的服务在应用程序级别是单例的,那么您需要在 AppModule 中导入带有服务的模块。对于 FeatureModule,您希望在没有任何服务的情况下导入 SharedModule - 否则,它可以创建自己的服务副本,覆盖应用程序级服务(即延迟加载的模块) - 这可能不是您想要的。

为此,您应该遵循从共享模块创建两个静态方法的约定:一个方法返回带有服务的模块,另一个方法返回不带服务的模块。

没有服务的只能由 FeatureModule 导入。有服务的应该由 AppModule 导入。

仅供参考,这就是存在 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: []
         }
     }
}

功能模块

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

应用模块

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

需要明确的是,提供者通常具有应用程序范围的根范围,而不管它提供在哪个模块中。这是因为提供者没有像组件那样的模块范围机制。唯一的例外是延迟加载模块 - 它引入了自己的子根范围。

【讨论】:

  • 功能组件如何从应用模块导入LookupService或从功能模块中引用的共享模块中导入组件,而无需引用.ts文件?
  • 你需要导入 ts 文件,即使是从共享模块中。
  • 所以虽然我有由共享模块导出的服务,该服务是导入我的功能模块的,但在功能组件中我仍然需要import { LookupService } from '../shared/lookup.service'; - 所以我在这里错过了这一点 - 无论如何我都在这样做从共享模块导出服务之前
【解决方案2】:

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

【讨论】:

  • 该服务运行良好,它是@injectable - 我正在经历一些重组和重构,并在此过程中试图了解有关模块如何工作的更多信息。@injectable 是一个运行时间问题 - 这不是构建问题。
猜你喜欢
  • 2016-07-21
  • 1970-01-01
  • 2020-10-14
  • 1970-01-01
  • 2015-12-28
  • 2022-01-11
  • 2022-01-21
  • 2017-10-01
  • 1970-01-01
相关资源
最近更新 更多