Angular dependency with “providedIn” in lazy loading modules

北城以北 提交于 2021-02-11 15:15:21

问题


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

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