Can I define a provider scope without listing all providers in that scope in Angular?

Discussão em 'Angular' iniciado por Charlie Harding, Novembro 20, 2024.

  1. I have some Angular services that store state, and I’d like these to be scoped to the appropriate component (and its subcomponents) to avoid leaking state between different instances of the same component. As there can be many services that exist in the same scope, and some are only referenced in lazy components, I’d like to specify the scope in the service rather than the scoping component.

    The current two options I’m aware of are as follows:


    1. Root provider

      @Injectable({ providedIn: 'root' }) class FirstService {}

      @Injectable({ providedIn: 'root' }) class SecondService {}

      @Component({}) class MyComponent {
      // same service instance for all component instances
      field = inject(FirstService)
      }


      This causes leaks between component instances, and is not tree-shakable for services not loaded in the first bundle.


    2. Explicit component provider

      @Injectable() class FirstService {}

      @Injectable() class SecondService {}

      @Component({ providers: [FirstService, SecondService] }) class MyComponent {
      // new service instance for each component instance
      field = inject(FirstService)
      }


      This is correctly separated, but it requires listing every service, and all services are loaded, even if they are not needed, or first needed in a lazy-loaded module.
    Ideal solution


    @Injectable({ scope: 'modal' }) class FirstService {}

    @Injectable({ scope: 'modal' }) class SecondService {}

    @Component({
    template: `@defer { <lazy-component /> }`
    providerScopes: ['modal'],
    imports: [LazyComponent],
    }) class MyComponent {
    // new service instance for each MyComponent instance
    service = inject(FirstService)
    }

    @Component({}) class LazyComponent {
    // new service instance for each MyComponent instance
    service = inject(SecondService);
    }


    This way the services are scoped correctly, but also not listed in the service, and so can be lazy-loaded by child components.

    Is there a way to achieve this?

    Continue reading...

Compartilhe esta Página