Подтвердить что ты не робот

Могут ли ленивые модули использовать один и тот же экземпляр службы, предоставляемой их родителями?

Я только столкнулся с проблемой с ленивым загруженным модулем, где родительский и дочерний модули требуют одинаковой службы, но создают экземпляр каждый. Объявление идентично для обоих, то есть

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)

Как мне это сделать, если я хочу использовать один и тот же экземпляр службы?

4b9b3361

Ответ 1

Используя forRoot, как упоминалось здесь, вам, вероятно, нужно. Проблема, которую он решил решить, напрямую связана с проблемой, с которой вы сталкиваетесь с ленивыми загруженными модулями, получая их собственный сервис.

Здесь описано Настроить основные службы с помощью forRoot, но этот раздел не объясняет проблему с ленивой загрузкой. Это объясняется небольшим предупреждением в конце Общие модули

Не указывать Singleton providers в приложении в общем модуле. Ленивый загруженный модуль, который импортирует этот общий модуль, сделает свою собственную копию службы.

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

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

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

Это гарантирует, что ленивый загруженный модуль не получит услугу. Но независимо от того, загружен ли модуль ленивым или нет, это шаблон, рекомендованный для служб приложения. Хотя следует отметить, что если у вас нет никакого ленивого загружаемого модуля, не используя forRoot patter и просто импортируя SharedModule, это будет только один экземпляр службы. Но эта модель должна по-прежнему рекомендуется соблюдать.


UPDATE

Наверное, я быстро ответил на вопрос, не глядя полностью на вопрос. В этом вопросе не упоминается какой-либо общий модуль. Кажется, что OP просто пытается добавить службу в @NgModule.providers как в модуле приложения, так и в ленивом загруженном дочернем модуле.

В этом случае просто удалите службу из дочернего модуля providers. Это не нужно. Для того, чтобы ребенок использовался, он добавлен в модуль приложения.

Просто помните, что providers являются приложениями широкими (за исключением случая, в котором этот пост имеет значение), а declarations - нет.

Ответ 2

Это должно работать, но все же я предлагаю вам пойти с концепцией 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
    };
  }
}

AppModule

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