问题
I am using Angular "Lazy-loading feature modules" as an example: live demo
CustomersModule is a lazy loading module i create a test service in customer module.
const routes: Routes = [
{
path: 'customers',
loadChildren: () => import('./customers/customers.module').then(m => m.CustomersModule)
},
{
path: 'orders',
loadChildren: () => import('./orders/orders.module').then(m => m.OrdersModule)
},
{
path: '',
redirectTo: '',
pathMatch: 'full'
}
];
import { Injectable } from '@angular/core';
@Injectable()
export class TestService {
constructor() { }
getHeroes() { return "HEROES"; }
}
in CustomersModule, add it to providers:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { CustomersRoutingModule } from './customers-routing.module';
import { CustomersComponent } from './customers.component';
import {TestService} from "./test.service";
@NgModule({
imports: [
CommonModule,
CustomersRoutingModule
],
providers: [
TestService
],
declarations: [CustomersComponent]
})
export class CustomersModule { }
CustomersModule also has a CustomersComponent, by this way i can use TestService in it.
import { Component, OnInit } from '@angular/core';
import {TestService} from "./test.service";
@Component({
selector: 'app-customers',
templateUrl: './customers.component.html',
styleUrls: ['./customers.component.css']
})
export class CustomersComponent implements OnInit {
testService: TestService;
constructor(test: TestService) {
this.testService = test;
}
ngOnInit() {
}
test(){
console.log(this.testService.getHeroes());
}
}
but when i remove the TestService from providers array of CustomersModule and use providedIn in TestService:
import { Injectable } from '@angular/core';
import {CustomersModule} from "./customers.module";
@Injectable({
providedIn: CustomersModule
})
export class TestService {
constructor() { }
getHeroes() { return "HEROES"; }
}
i got this error:
core.js:6228 ERROR Error: Uncaught (in promise): ReferenceError: Cannot access 'CustomersModule' before initialization
ReferenceError: Cannot access 'CustomersModule' before initialization
at Module.CustomersModule (customers.component.ts:9)
at Module../src/app/customers/test.service.ts (test.service.ts:5)
at __webpack_require__ (bootstrap:84)
at Module../src/app/customers/customers.component.ts (customers-customers-module.js:78)
at __webpack_require__ (bootstrap:84)
at Module../src/app/customers/customers-routing.module.ts (customers-customers-module.js:29)
at __webpack_require__ (bootstrap:84)
at Module../src/app/customers/customers.module.ts (customers.component.ts:9)
at __webpack_require__ (bootstrap:84)
at ZoneDelegate.invoke (zone-evergreen.js:364)
at resolvePromise (zone-evergreen.js:798)
at resolvePromise (zone-evergreen.js:750)
at zone-evergreen.js:860
at ZoneDelegate.invokeTask (zone-evergreen.js:399)
at Object.onInvokeTask (core.js:41632)
at ZoneDelegate.invokeTask (zone-evergreen.js:398)
at Zone.runTask (zone-evergreen.js:167)
at drainMicroTaskQueue (zone-evergreen.js:569)
I know there is circular dependecny here, for eagerly loaded modules it works and will enable tree-shaking. Does it mean in lazy loading modules only providers array can be used in NgModule?
are there guidelines/best practice for this?
回答1:
There is definitely circular dependency, that looks like this
CustomersComponent -> TestService -> CustomersModule -> CustomersComponent -> TestService
that's why you are getting this exception CustomersModule and TestService
are injecting one another, so injecting it's in the provider array (instead of providedIn), will do the same thing, so undo your changes and leave TestService
in providers array. Angular will optimize it the same way as it would do for providedIn
attribute
回答2:
try like this.
@Injectable({
providedIn: 'root'
})
Let me know if you still face any issue.
回答3:
See this issue. The providedIn property is extremely confusing in this aspect.
Does it mean in lazy loading modules only providers array can be used in NgModule?
Yes, so, unfortunately, tree-shaking is out of the picture with lazy-loaded modules.
来源:https://stackoverflow.com/questions/62424077/angular-dependency-with-providedin-in-lazy-loading-modules