乐趣区

关于前端:Angular-应用里-NullInjectorError-No-provider-for-XX-错误的一个场景和分析过程

最近解决客户 incident,有个客户从 Spartacus 4 降级到 5.2 之后,启动 Storefront,console 遇到了一个谬误音讯:

NullInjectorError – No provider for AnonymousConsentTemplatesAdapter!

引起这个谬误音讯的场景有很多,这个 incident 最初的场景是:

以前的 module 通过 loaded for root 实现,当初改成了 loaded with module 来实现。

在 Angular 中,模块(Module)是组织代码的根本单元。在应用 Angular 模块时,有两种形式能够将模块加载到应用程序中:通过 “loaded for root”(根加载)和通过 “loaded with module”(模块加载)。这两种加载形式有一些区别,上面我将具体阐明它们,并提供一些例子来阐明其用法和成果。

  1. Loaded for root(根加载):
    当咱们将一个模块加载为根模块时,它意味着该模块将被整个应用程序共享和应用。根模块在应用程序启动时被加载,并且在整个应用程序的生命周期中放弃加载状态。

例子:
假如咱们有一个名为 “SharedModule” 的模块,其中定义了一些罕用的组件、指令和服务,咱们心愿这些性能在整个应用程序中都可用。咱们能够将 “SharedModule” 模块加载为根模块。

// shared.module.ts
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {SharedComponent} from './shared.component';
import {SharedDirective} from './shared.directive';
import {SharedService} from './shared.service';

@NgModule({declarations: [SharedComponent, SharedDirective],
  imports: [CommonModule],
  providers: [SharedService],
  exports: [SharedComponent, SharedDirective]
})
export class SharedModule {}
// app.module.ts
import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {SharedModule} from './shared/shared.module';

@NgModule({imports: [BrowserModule, SharedModule],
  declarations: [AppComponent],
  bootstrap: [AppComponent]
})
export class AppModule {}

在这个例子中,咱们将 “SharedModule” 加载为根模块,并将其导入到应用程序的根模块 “AppModule” 中。这样,”SharedModule” 中定义的组件、指令和服务就能够在整个应用程序中应用,而不须要每个模块都去导入和配置它们。

  1. Loaded with module(模块加载):
    当咱们将一个模块加载到另一个模块中时,它意味着该模块仅在该特定模块的上下文中可用。模块加载产生在特定的功能模块中,并且只在该模块及其子模块中失效。

例子:
假如咱们有一个名为 “FeatureModule” 的模块,其中蕴含了一些特定的性能组件、指令和服务,咱们心愿这些性能仅在 “FeatureModule” 及其子模块中可用。咱们能够将 “FeatureModule” 加载到另一个模块中。

// feature.module.ts
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {FeatureComponent} from './feature.component';
import {FeatureDirective} from './feature.directive';
import {FeatureService} from './feature.service';

@NgModule({declarations: [FeatureComponent, FeatureDirective],
 

 imports: [CommonModule],
  providers: [FeatureService],
  exports: [FeatureComponent, FeatureDirective]
})
export class FeatureModule {}
// main.module.ts
import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {FeatureModule} from './feature/feature.module';

@NgModule({imports: [BrowserModule, FeatureModule],
  declarations: [AppComponent],
  bootstrap: [AppComponent]
})
export class MainModule {}

在这个例子中,咱们将 “FeatureModule” 加载到另一个模块 “MainModule” 中。这样,”FeatureModule” 中定义的组件、指令和服务仅在 “MainModule” 及其子模块中可用,不会对应用程序的其余模块产生影响。

区别总结:

  • “Loaded for root”(根加载)实用于那些心愿在整个应用程序中共享和应用的模块,能够被所有模块拜访和调用。
  • “Loaded with module”(模块加载)实用于那些心愿在特定模块及其子模块中应用的模块,能够提供特定性能的模块封装,防止全局净化。

根加载能够使模块的性能在整个应用程序中易于拜访和应用,而模块加载能够实现模块化的性能封装和部分可用性。依据我的项目需要和代码组织的指标,能够抉择适当的加载形式来实现最佳的代码构造和可维护性。

退出移动版