延迟加载的模块可以共享父级提供的服务的同一实例吗?

时间:2016-09-24 05:18:21

标签: angular angular2-services

我刚遇到一个延迟加载模块的问题,其中父模块和子模块都需要相同的服务但​​每个都创建一个实例。声明对两者都是相同的,即

import { MyService } from './my.service';
...
@NgModule({
   ...
   providers: [
      MyService,
      ...
   ]
});

这是路由设置

export parentRoutes: Routes = [
   { path: ':id', component: ParentComponent, children: [
      { path: '', component: ParentDetailsComponent },
      { path: 'child', loadChildren: 'app/child.module#ChildModule' },
      ...
   ]}
];

当然,然后在父模块中导入为

RouterModule.forChild(parentRoutes)

如果我想共享同一个服务实例,我该怎么做呢?

3 个答案:

答案 0 :(得分:50)

使用forRoot,如上所述here,可能就是您所需要的。它要解决的问题与您在使用延迟加载的模块获得自己的服务时遇到的问题直接相关。

这是在Configure core services with forRoot中解释的,但该部分没有解释延迟加载问题。这可以通过Shared Modules

结尾处的一点警告来解释
  

不要在共享模块中指定应用程序范围的单例providers。导入该共享模块的延迟加载模块将创建自己的服务副本。

@NgModule({})
class SharedModule {
  static forRoot() {
    ngModule: SharedModule,
    providers: [ MyService ]
  }
}

@NgModule({
  import: [ SharedModule.forRoot() ]
})
class AppModule {}

@NgModule({
  imports: [ SharedModule ]
})
class LazyLoadedModule {}

这可确保延迟加载的模块无法获取服务。但是,无论模块是否延迟加载,这都是推荐用于应用程序范围的服务的模式。虽然应该注意,如果你没有任何延迟加载模块,不使用forRoot模式,只导入SharedModule,它只会是服务的一个实例。但是仍然建议遵循这种模式。

更新

我想我在没有完全看到这个问题的情况下迅速回答。在这个问题中, 没有提及任何共享模块。 OP似乎只是试图将服务添加到app模块和延迟加载的子模块中的@NgModule.providers

在这种情况下,只需从子模块providers中删除该服务即可。这不是必需的。 app模块中添加的内容足以让孩子使用。

请记住providers是应用范围广(除了此帖子的问题情况),而declarations则不是。

答案 1 :(得分:15)

这应该有效,但我仍然建议您使用 SharedModule 概念,其中包含常用 服务,管道,指令和组件。< / p>

<强>共享/ SharedModule

import { NgModule,ModuleWithProviders } from '@angular/core';
import { CommonModule }        from '@angular/common';

import { MyService } from './my.service';

@NgModule({
  imports:      [ CommonModule ],
  declarations: [],
  exports:      [ CommonModule ]
})
export class SharedModule {
  static forRoot(): ModuleWithProviders {
    return {
      ngModule: SharedModule,
      providers: [ MyService ]                       //<<<====here
    };
  }
}

<强>的AppModule

import {SharedModule} from './shared/shared.module';
...
@NgModule({
   imports:[ BrowserModule,SharedModule.forRoot()],  //<<<====here
   providers: []
});

答案 2 :(得分:0)

我有一个带有服务的单独的布局模块,该服务需要使用延迟加载在其他功能模块上工作

我能够通过直接从布局模块导出服务来解决问题

@NgModule({
    declarations: [...],
    imports: [...],
    exports: [...],
})
export class LayoutModule {
    ...
}

export { LayoutService }