Współdzielenie tego samego elementu drzewa DI
Do tej pory naszym problemem jest to, że tworzymy dwa wystąpienia tych samych usług na różnych poziomach drzewa DI. Instancja utworzona w dolnej gałęzi drzewa jest dodatkowo zdefiniowana na poziomie katalogu głównego. Chcemy uniknąć tworzenia drugiej instancji na niższym poziomie drzewa DI dla modułu załadowanego z opóźnieniem i używać tylko instancji usługi zarejestrowanej w katalogu głównym drzewa.
Aby to osiągnąć, musimy zmodyfikować definicję SharedModule
i zamiast definiować naszą usługę w własnościprovider
, musimy stworzyć statyczną metodę o nazwie forRoot
, która eksportuje usługę wraz z samym modułem.
app/shared/shared.module.ts
import { NgModule, ModuleWithProviders } from '@angular/core';
import { CounterService } from './counter.service';
@NgModule({})
export class SharedModule {
static forRoot(): ModuleWithProviders {
return {
ngModule: SharedModule,
providers: [CounterService]
};
}
}
Za pomocą tej konfiguracji możemy zaimportować ten moduł do naszego modułu głównego AppModule
wywołującego metodęforRoot
w celu zarejestrowania modułu i usługi.
app/app.module.ts
...
import { SharedModule } from './shared/shared.module';
@NgModule({
imports: [
SharedModule.forRoot(),
...
],
...
})
export class AppModule {}
Powinniśmy wywoływać forRoot
tylko w głównym module aplikacji i nigdzie indziej. Gwarantuje to, że tylko jedna instancja usługi istnieje na poziomie katalogu głównego. Wywołanie forRoot
w innym module może ponownie zarejestrować usługę na innym poziomie drzewa DI.
Ponieważ SharedModule
zawiera tylko usługę, którą Angular rejestruje w iniektorze aplikacji root, nie musimy go importować doLazyModule
. Jest tak dlatego, że załadowany z opóźnieniem moduł będzie już miał dostęp do usług zdefiniowanych na poziomie głównym.
Zobacz przykład [056]
Tym razem za każdym razem, gdy zmieniamy wartość właściwości 'counter', ta wartość jest dzielona między EagerComponent
iLazyComponent
, co potwierdza, że używamy tego samego wystąpienia CounterService
.
Jest jednak bardzo prawdopodobne, że możemy mieć komponent, potok lub dyrektywę zdefiniowaną w SharedModule
, której potrzebujemy w innym module. Wykonaj na przykład następujące czynności .
app/shared/shared.module.ts
import { NgModule, ModuleWithProviders } from '@angular/core';
import { CounterService } from './counter.service';
import { HighlightDirective } from './highlight.directive';
@NgModule({
declarations: [HighlightDirective],
exports: [ HighlightDirective ]
})
export class SharedModule {
static forRoot(): ModuleWithProviders {
return {
ngModule: SharedModule,
providers: [CounterService]
};
}
}
Tutaj deklarujemy i eksportujemy HighlightDirective
, aby inne moduły importująceSharedModule
mogły używać go w swoich szablonach. Oznacza to, że możemy po prostu zaimportować moduł do LazyModule
normalnie.
app/lazy/lazy.module.ts
import { NgModule } from '@angular/core';
import { SharedModule } from '../shared/shared.module';
import { LazyComponent } from './lazy.component';
import { routing } from './lazy.routing';
@NgModule({
imports: [
SharedModule,
routing
],
declarations: [LazyComponent]
})
export class LazyModule {}
Teraz możemy użyć tej dyrektywy w LazyModule
bez tworzenia kolejnej instancjiCounterService
.
Zobacz przykład [057]