How do I provide a service in a lazy-loaded module and have that service scoped to just the lazy-loaded module and its components?

杀马特。学长 韩版系。学妹 提交于 2019-11-27 04:47:58

问题


In the angular docs FAQ section it states, "Unlike providers of the modules loaded at launch, providers of lazy-loaded modules are module-scoped." link

Does 'module-scoped' here mean just the module or does it extend to include all components belonging to that module?

The reason I ask is because I have a lazy-loaded module with 2 components that belong to it. I register a service in the module but for some reason each component is getting a different instance of that service.

What do I need to change in order to provide LazyModuleService in my lazy-loaded module and have that service scoped to just the lazy-loaded module and it's components? Please include any additional files needed. I've tried to make a generic example to help anyone else who might find this question.

Lazy-loaded module:

import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { Component1 } from './component1.component';
import { Component2 } from './component2.component';
import { LazyModuleService } from './lazy-module.service';

@NgModule({
  imports: [
    CommonModule,
  ],
  declarations: [
    Component1,
    Component2,
  ],
})

export class LazyLoadedModule { }

回答1:


How lazy loading works:

After some deep investigation, it seems as though the problem is related to how lazy loading is implemented.

In your case, your lazy loaded module actually had routing to 2 different components within it - both of those components were directly exposed as Router.forChild routes. But, as a result, when you navigated to each component, a separate instance of your lazy loaded module's providers were added to each component.

Since you actually wanted all of the components in the lazy loaded module to share the same instance of their provided services, you need to create a single 'root' component and then have your two components be children of that root component.

It seems as though when lazy loading, the providers in your module will be added to the injector of the component at the root of your module. Since you have two 'root components', they each got separate instances of the services.

The solution was to create a single root component whose injector will receive the lazy loaded services, which can then be shared by any child components.




回答2:


Simply add your LazyModuleService as a provider in your LazyLoadedModule. You'll be able to use it only in the components in that module.




回答3:


Great built-in solution provided by Angular 6. If you're using Angular 6+ (check your package.json to find out), you can provide application-wide services in a different way.

Instead of adding a service class to the providers[] array in AppModule , you can set the following config in @Injectable() :

@Injectable({providedIn: 'root'})
export class MyService { ... }

This is exactly the same as:

export class MyService { ... }

and

import { MyService } from './path/to/my.service';

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

Using this new syntax is completely optional, the traditional syntax (using providers[] ) will still work. The "new syntax" does offer one advantage though: Services can be loaded lazily by Angular (behind the scenes) and redundant code can be removed automatically. This can lead to a better performance and loading speed - though this really only kicks in for bigger services and apps in general.

Source : Udemy



来源:https://stackoverflow.com/questions/42861429/how-do-i-provide-a-service-in-a-lazy-loaded-module-and-have-that-service-scoped

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!