Circular Dependency w Angular

Jak uniknąć efektu circular dependency?

Angular dostarcza nam prosty sposób na dynamiczne generowanie komponentów, ale czasami pojawia się problem.

Photo by Alvaro Reyes on Unsplash

Problem

Załóżmy, że mamy dwa komponenty i serwis do dynamicznego renderowanie komponentów. Serwis posiada metodę render, która akceptuje typ komponentu jako argument np. OneComponent.

OneComponent używa naszego serwisu do wyrenderowania komponentu TwoComponent, a komponent TwoComponent używa serwisu do wyrenderowania komponentu OneComponent.

Ostrzeżenie circular dependency

Dzieje się to, ponieważ OneComponent importuje TwoComponent, a TwoComponent importuje OneComponent. Chaos, prawda?

Jakiś czas temu odkryłem ciekawy sposób na rozwiązanie tego problemu. W tym celu użyjemy InjectionsTokens i dodamy je do naszego komponentu jako providers.

Stwórzmy COMPONENT_ONE_TOKEN (COMPONENT_TWO_TOKEN token jest stworzony podobnie).

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

export const COMPONENT_ONE_TOKEN = new InjectionToken<any>('ComponentOneToken');

Dodajmy tokeny w module

@NgModule({
  imports: [
    CommonModule,
  ],
  declarations: [
    OneComponent,
    TwoComponent
  ],
  entryComponents: [
    OneComponent,
    TwoComponent
  ],
  providers: [
    RenderService,
    { provide: COMPONENT_ONE_TOKEN, useValue: OneComponent },
    { provide: COMPONENT_TWO_TOKEN, useValue: TwoComponent }
  ]
})
export class SomeModule {
}

Pozwala nam to na wstrzyknięcie klas komponentów

@Component({
  selector: 'app-one',
  templateUrl: './one.component.html',
  styleUrls: ['./one.component.scss']
})
export class OneComponent {
  constructor(@Inject(COMPONENT_TWO_TOKEN) private componentTwo) {
  }
}

Zmieni to sposób używamy metody render w serwisie z service.render(TwoComponent) na service.render(this.componentTwo).

Podsumowanie

Rozwiązanie jest dość skomplikowane. Innym sposobem jest na pewno lepsza architektura komponentów, która nie doprowadzi do ostrzeżeń o circular dependency. Czasami się nie da.

Udostępnij
Default image
Wojciech Szućko
Jestem Angular Developerem. Przedstawiam techniki i technologie, które wykorzystuje w codziennej pracy z web aplikacjami. Tworzyłem projekty między innymi dla Bank Pekao S.A., AlphaTauri czy Playmobil.