BrowserAnimationsModule 在核心模块中导入时不起作用

BrowserAnimationsModule does not work when imported in core module

我将较大的应用程序划分为模块(功能模块、核心模块和共享模块)。我正在使用 Angular Material,因此我导入了 BrowserAnimationsModule。我将它放在共享模块中并且一切正常,但是当我想延迟加载一些功能模块时出现问题 - 然后我有关于 BrowserModules 的双重导入错误。我知道 BrowserAnimationsModule 应该由核心模块导入,但是当我尝试这样做时,出现以下错误:

Uncaught Error: Template parse errors:
Can't bind to 'ngForOf' since it isn't a known property of 'mat-option'.
1. If 'mat-option' is an Angular component and it has 'ngForOf' input, then verify that it is part of this module.
2. If 'mat-option' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.
3. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component. ("' | translate}}" (change)="change()" [(ngModel)]="actualFilter" name="food">
          <mat-option [ERROR ->]*ngFor="let filterColumn of displayedColumns" [value]="filterColumn">
            {{filterColumn | t"): ng:///ChargesModule/ChargesComponent.html@9:22
Property binding ngForOf not used by any directive on an embedded template. Make sure that the property name is spelled correctly and all directives are listed in the "@NgModule.declarations". ("COLUMNFILTER' | translate}}" (change)="change()" [(ngModel)]="actualFilter" name="food">
          [ERROR ->]<mat-option *ngFor="let filterColumn of displayedColumns" [value]="filterColumn">
            {{filt"): ng:///ChargesModule/ChargesComponent.html@9:10

下面我介绍模块: app.module.ts:

    @NgModule({
      declarations: [
        AppComponent
      ],
      imports: [
        BrowserModule,
        HomeModule,
        ChargesModule,
        ModeratorPanelModule,
        CoreModule
      ],
      providers: [],
      bootstrap: [AppComponent]
    })

    export class AppModule { }

core.module.ts:

 @NgModule({
      imports: [
        HttpModule,
        HttpClientModule,
        AppRoutingModule,
        SharedModule,
        BrowserAnimationsModule
      ],
      declarations: [
        SidenavComponent,
        HeaderComponent,
        ErrorPageComponent,
        PageNotFoundComponent,
        LoginComponent,
        UpdatePanelComponent,
        DialogConfirmCancelComponent,
        ConfirmMessageComponent,
      ],
      exports: [
        HttpModule,
        HttpClientModule,
        SharedModule,
        HeaderComponent,
        SidenavComponent,
        AppRoutingModule,
        BrowserAnimationsModule
      ],
      providers: [
        AuthService, AuthGuard, HttpAuthService, DictionariesService,
        DictionaryItemFactory, CanDeactivateGuard, { provide: MatPaginatorIntl, useClass: CustomPaginator }
      ],
      entryComponents: [DialogConfirmCancelComponent, ConfirmMessageComponent]
    })
    export class CoreModule { }

shared.module.ts:

export function HttpLoaderFactory(http: HttpClient) {
  return new TranslateHttpLoader(http);
}
@NgModule({
  imports: [
    CommonModule,
    MaterialModule,
    FlexLayoutModule,
    CdkTableModule,
    FormsModule,
    NgbModule.forRoot(),
    TimepickerModule.forRoot(),
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: HttpLoaderFactory,
        deps: [HttpClient]
      }
    })
  ],
  exports: [
    NgbModule,
    TimepickerModule,
    TranslateModule,
    CurrenciesComponent,
    MaterialModule,
    FlexLayoutModule,
    CdkTableModule,
    FormsModule,
    DropDownListComponent,
    DictionariesComponent
  ],
  declarations: [
    DictionariesComponent,
    DropDownListComponent
  ],
  providers: []
})
export class SharedModule { }

在 MaterialModule 中,我已经将所有材质模块与 CommonModule 一起导入。

如果您遇到类似

的错误

Can't bind to 'ngForOf' since it isn't a known property

那么你应该知道它是:

  • 与未申报有关 @Input;

  • 或者您的 @NgModule 配置有问题

由于ngForOf是内置指令,让我们分析一下您的@NgModule配置有什么问题。

首先我们需要确定这个错误是从哪里来的。从报错信息中不难看出:

{{filterColumn | t"): ng:///ChargesModule/ChargesComponent.html@9:22

很明显,ChargesComponentChargesModule 的一部分,我们收到了错误。我相信 ChargesModule 声明看起来像:

charges.module.ts

@NgModule({
  imports: [
    SharedModule,
    ...
  ],
  declarations: [
    ChargesComponent,
    ...
  ]
})
export class ChargesModule {}

现在,如果您还没有阅读我之前的回答 ,我强烈建议您阅读。确保您了解 component/directive/pipe 如何在其他模块中使用。如果您这样做,那么只需从 SharedModule 导出 CommonModule,如果您仍然有疑问,请继续阅读...

这里的主要规则是

由于我们需要在 ChargesComponent 模板中使用 ngForOf 指令,它是 ChargesModule 的一部分,因此该指令应该是可传递 ChargesModule 中指令的一部分。

这些指令是如何收集的?

               ChargesModule.directives 
                         + 
      exported directives from imported @NgModules
                        ||
         ChargesModule.transitiveModule.directives

乍一看,我们会在 ChargesModule 声明数组中声明 ngForOf 指令,但 ngForOf 已经在 CommonModule 中声明,并且指令必须是 only 的一部分一个模块我们做不到。

因此继续在导入的 @NgModules 中寻找 ngForOf 个指令。好吧,我们导入了SharedModule让我们看看它导出了哪些指令:

shared.module.ts

@NgModule({
  ...,
  exports: [
    NgbModule,
    TimepickerModule,
    TranslateModule,
    CurrenciesComponent,
    MaterialModule,
    FlexLayoutModule,
    CdkTableModule,
    FormsModule,
    DropDownListComponent,
    DictionariesComponent
  ]
})
export class SharedModule { }

SharedModule 导出所有

的指令

@NgModules

导出
 NgbModule,
 TimepickerModule,
 TranslateModule,
 MaterialModule,
 FlexLayoutModule,
 CdkTableModule,
 FormsModule

这意味着如果 NgbModule 有导出指令,那么它们将被添加到 SharedModule 的导出指令中。

或仅包含在 exports 数组

中的指令
 CurrenciesComponent,
 DropDownListComponent,
 DictionariesComponent

因为我们在这里没有看到 CommonModule 我们可以假设我们会得到错误 Can't bind to 'ngForOf'

为了解决这个问题,我们必须将 CommonModule 添加到 exports 数组,一切都应该按预期工作。

好问题是

However, I do not understand why this problem occured only after moving of BrowserAnimationsModule from Shared to Core module. Can you explain that?

不知道BrowserAnimationsModule长什么样就很难理解。让我们通过查看 source code:

来获得启示
@NgModule({
  exports: [BrowserModule],
  providers: BROWSER_ANIMATIONS_PROVIDERS,
})
export class BrowserAnimationsModule {
}

并查看 BrowserModule:

@NgModule({
  ...
  exports: [CommonModule, ApplicationModule]
})
export class BrowserModule {

很明显,如果我们从 SharedModule 中导出 BrowserAnimationsModule 模块,我们也会从 CommonModule 中导出指令,因为:

SharedModule.transitiveModule.directives
               /\
               ||
   BrowserAnimationsModule exports 
               /\
               ||
     BrowserModule that exports
               /\
               ||   
          CommonModule

所以在将 BrowserAnimationModule 移动到 CoreModule 之后,您的 SharedModule 不再导出 ngForOf 指令,这就是您收到错误的原因。