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

时间:2017-12-14 20:40:11

标签: angular

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

@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,导入工作正常)

谢谢! 阿南德

2 个答案:

答案 0 :(得分:2)

服务是具有根范围的单例。如果您想确保您提供的服务是应用程序级别的单件,那么您需要在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{ }

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

答案 1 :(得分:0)

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