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

Tho*_*der 31 angular2-services angular

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

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

这是路由设置

export parentRoutes: Routes = [
   { path: ':id', component: ParentComponent, children: [
      { path: '', component: ParentDetailsComponent },
      { path: 'child', loadChildren: 'app/child.module#ChildModule' },
      ...
   ]}
];
Run Code Online (Sandbox Code Playgroud)

当然,然后将其导入父模块中

RouterModule.forChild(parentRoutes)
Run Code Online (Sandbox Code Playgroud)

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

Pau*_*tha 50

使用forRoot,提到这里,是你所需要的可能.它要解决的问题与您在使用延迟加载的模块获得自己的服务时遇到的问题直接相关.

这里解释了配置核心服务forRoot,但该部分没有解释延迟加载问题.这可以通过共享模块末尾的一点警告来解释

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

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

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

@NgModule({
  imports: [ SharedModule ]
})
class LazyLoadedModule {}
Run Code Online (Sandbox Code Playgroud)

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


UPDATE

我想我没有完全看到这个问题就赶紧回答.在这个问题中,没有任何共享的模块的提及.看起来OP只是试图将服务添加到@NgModule.providersapp模块和延迟加载的子模块中.

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

请记住,这providers是适用范围广(除了在这个帖子的问题情况下),而declarations不是.


mic*_*yks 16

这应该工作,但我仍然建议你使用SharedModule概念,其中包含常见的 服务,管道,指令和组件.

共享/ 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
    };
  }
}
Run Code Online (Sandbox Code Playgroud)

的AppModule

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

  • 共享模块仅包含公共指令,组件和管道,但不包含服务.服务与功能相关,在大多数情况下不能放在共享模块中.如果必须共享服务,请使用角度文档中描述的`forRoot()`方法. (8认同)