简体   繁体   English

Angular 依赖于延迟加载模块中的“providedIn”

[英]Angular dependency with “providedIn” in lazy loading modules

I am using Angular "Lazy-loading feature modules" as an example: live demo我以Angular“延迟加载功能模块”为例: live demo

CustomersModule is a lazy loading module i create a test service in customer module. CustomersModule是一个延迟加载模块,我在客户模块中创建了一个测试服务。

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:在 CustomersModule 中,将其添加到提供程序:

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. CustomersModule 也有一个CustomersComponent ,通过这种方式我可以在其中使用 TestService。

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:但是当我从CustomersModule的提供者数组中删除TestService并在TestService中使用providedIn时:

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.我知道这里有循环依赖,对于急切加载的模块,它可以工作,并且会启用 tree-shaking。 Does it mean in lazy loading modules only providers array can be used in NgModule?这是否意味着在延迟加载模块中只能在 NgModule 中使用提供者数组?

are there guidelines/best practice for this?有这方面的指导方针/最佳做法吗?

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.这就是为什么您会收到此异常的原因, CustomersModule and TestService相互注入,因此将其注入提供程序数组(而不是提供的 In)中,将执行相同的操作,因此撤消您的更改并将TestService保留在提供程序数组中。 Angular will optimize it the same way as it would do for providedIn attribute Angular 将像对providedIn的属性一样优化它

try like this.试试这样。

@Injectable({
  providedIn: 'root'
})

Let me know if you still face any issue.如果您仍然遇到任何问题,请告诉我。

See this issue.看到这个问题。 The providedIn property is extremely confusing in this aspect.在这方面,providedIn 属性非常令人困惑。

Does it mean in lazy loading modules only providers array can be used in NgModule?这是否意味着在延迟加载模块中只能在 NgModule 中使用提供者数组?

Yes, so, unfortunately, tree-shaking is out of the picture with lazy-loaded modules.是的,所以,不幸的是,对于延迟加载的模块,摇树是不可能的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM