From my last post:
The input component approach can be extended to rely on services to be configured in business modules so that the same common component used by each module has different interactions.
However, through practice, it is feasible to configure in lazy loading module. In the acute load module configuration is an accident!
Angular – Multilevel dependency injectors can be read from “element injectors”. There’s actually an interesting one:
The ability to reconfigure one or more providers at different levels opens up some interesting and useful possibilities.
The key
Then it’s time to show real technology. The complete code
Preliminary knowledge
Service provider
Make an analogy: make a phone call can be regarded as a service provided by telecom, then telecom can be regarded as the provider of this service. If telecom were the only company, it would be impossible to use the phone service without it. Then the service provider is needed to consume the service.
Through layers of “proxies,” modules can provide services, and components can also provide services. They provide services in their own sphere.
Classification of services
The following examples are provided in a tree-shaker optimized manner; The exception is provided by the component, because normally the component would need to use the methods or data of the service, which would create circular dependencies.
Suggestion: Provide the service in the top-level business module or component, and in its sub-component, get the instance or method or value of the service through the bubbling feature of the injector.
1. Singleton service
There are two ways to generate a singleton service in Angular: declare that the service should be provided at the root of the application. Include the service in the AppModule or in a module that will only be imported by AppModule.
// @injectable ({providedIn:'root'}} @NgModule({imports: [CommonModule], declarations: [], providers: [ShareModuleConfigService], })exportclass CoreModule { } @NgModule({ imports: [ CoreModule, // .... ] , declarations: [AppComponent], bootstrap: [AppComponent], providers: [] })export class AppModule { }
Copy the code
2. Module-level service
@Injectable({
providedIn: EagerlyLoadedModule
})Copy the code
3. Component-level services
@Component({
selector: 'app-index',
templateUrl: './index.component.html',
styleUrls: ['./index.component.css'],
providers: [IndexService]
})Copy the code
The sample
Folder structure. Submodule default page IndexComponent
1. Preparation
(1) The root component has the helloComponent
(2) There is also helloComponent in index.component.html of each sub-module
(3) The helloComponent in the Share module will be displayed using the values in ShareModuleConfigService
exportclass HelloComponent implements OnInit { @Input() txt: string; Constructor (// Optional() private config: ShareModuleConfigService) {}ngOnInit() { this.txt = this.config ? this.config.helloCompTxt : null; }}Copy the code
(4) We also have a singleton ShareModuleConfigService provided by the coreModule (ShareModuleConfigService). This configuration can be modified to customize some of the presentations or interactions of the Share module.
@Injectable()
export class ShareModuleConfigService {
helloCompTxt: string;
data = [1];
constructor() {
console.log('ShareModuleConfigService constructor'); }}Copy the code
(5) Simply configure them using useValue:
providers: [
{
provide: ShareModuleConfigService,
useValue: {
helloCompTxt: 'Lazy module, let's do hello.',
data: [4]
}
}
]Copy the code
(6) We’ll see how the helloComponent displays at different levels on the page.
2. Lazily load the configuration in the module
First comment out the EagerlyLoadedModule from the AppModule imports in the sample code and you’ll see what happens.
The root component shows the initial value of ShareModuleConfigService
Then, click “Lazy load module” and you will see:
After the lazy module modification, the initial values are changed to achieve module-level configuration
Index.component.ts = index.component.ts = index.component.ts = index.component.ts = index.component.ts = index.component.ts = index.component.ts = index.component.ts = index.component.ts So you’ll see something like this.
Component configuration, “overrides” the configuration of the module
It is also worth noting that the values used by the root component do not change, which can be interpreted as the lazy module instantiating the singleton service once more. They completely separate the two. This enables each lazy module to have its own configuration to implement different interactions or functions of components, directives, and pipes in the SHARE module.
3. Modify configurations in the acute module
The same process as before, but at first you will see a different result. Remove previous comments from AppModule. Load the acute module into the application.
The value of the root component has been modified directly
Then, put the CoreModule in the AppModule last
The value of the root component has not changed
Isn’t that amazing? In fact, the official explanation has been given. Let’s take a look.
The root AppModule imports the CoreModule and adds its providers to the AppModule’s service providers. In particular, Angular adds these imported service providers before @NgModule.providers. This order ensures that service providers in the AppModule will always take precedence over those imported from other modules
angular.cn/guide/singl…
Therefore, if you want to ensure the uniqueness of the singleton service, you must place the CoreModule behind all other modules to avoid interference from the acute module.
The configuration of child components is not mentioned, as is the case with lazy modules. Having said that, there are many points mentioned in this article. Now to sum up:
1. Lazy module If you need to configure the share module, you can directly configure the share module by taking advantage of the new instance created by the lazy module.
2. If the share module needs to be configured in the acute module, the share module cannot be configured in the acute module. The share module is overwritten by the singleton service or the singleton service. You can do this by moving the configuration into the root component of the module.
3. The value of the singleton service is changed by the component in the acute module, but the value in the root module is not changed. As you can see, the flow of values in Angular is one-way from top to bottom. Like an upside-down tree, nutrients (data) are passed from the root (root components) to the branches.
Reference:
Presents the cn/guide/singl…
Presents the cn/guide/provi…