Opóźnione ładowanie i drzewo wstrzykiwania zależności

Moduły ładowane z opóźnieniem tworzą własne gałęzie na drzewie Dependency Injection (DI). Oznacza to, że możliwe jest posiadanie usług należących do modułu ładowanego z opóźnieniem, które nie są dostępne przez moduł główny ani żaden inny moduł naszej aplikacji.

Aby pokazać to zachowanie, kontynuujmy przykład poprzedniej sekcji i dodaj CounterService do naszegoLazyModule.

app/lazy/lazy.module.ts

...
import { CounterService } from './counter.service';

@NgModule({
  ...
  providers: [CounterService]
})
export class LazyModule {}

Tutaj dodaliśmy CounterService do tablicyprovider. Klasa CounterService jest prostą klasą, która zawiera odniesienie do własności counter.

app/lazy/counter.service.ts

import { Injectable } from '@angular/core';

@Injectable()
export class CounterService {
  counter = 0;
}

Możemy zmodyfikować LazyComponent do korzystania z tej usługi za pomocą przycisku, aby zwiększyć właściwośćcounter.

app/lazy/lazy.component.ts

import { Component } from '@angular/core';

import { CounterService } from './counter.service';

@Component({
  template: `
    <p>Lazy Component</p>
    <button (click)="increaseCounter()">Increase Counter</button>
    <p>Counter: {{ counterService.counter }}</p>
  `
})
export class LazyComponent {

  constructor(public counterService: CounterService) {}

  increaseCounter() {
    this.counterService.counter += 1;
  }
}

Zobacz przykład [071]

Usługa działa. Jeśli zwiększymy licznik, a następnie nawigujemy w przód iw tył między trasami eager ilazy, wartość counter będzie utrzymywać się w leniwym załadowanym module.

Ale pytanie brzmi: jak możemy sprawdzić, czy usługa jest odizolowana i czy nie można jej użyć w komponencie należącym do innego modułu? Spróbujmy użyć tej samej usługi w EagerComponent.

app/eager.component.ts

import { Component } from '@angular/core';
import { CounterService } from './lazy/counter.service';

@Component({
  template: `
    <p>Eager Component</p>
    <button (click)="increaseCounter()">Increase Counter</button>
    <p>Counter: {{ counterService.counter }}</p>
  `
})
export class EagerComponent {
  constructor(public counterService: CounterService) {}

  increaseCounter() {
    this.counterService.counter += 1;
  }
}

Jeśli spróbujemy uruchomić tę nową wersję naszego kodu, otrzymamy komunikat o błędzie w konsoli przeglądarki:

No provider for CounterService!

Co ten błąd mówi nam, że AppModule, gdzie zdefiniowanoEagerComponent, nie ma wiedzy o usłudze o nazwie CounterService. CounterService funkcjonuje w innej gałęzi drzewa DI utworzonego dla LazyModule, gdy był on leniwy załadowany w przeglądarce.