首页 文章

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

提问于
浏览
2

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

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一起导入 .

1 回答

  • 5

    如果您遇到类似的错误

    无法绑定到'ngForOf',因为它不是已知属性

    那么你应该意识到它:

    • 与未声明的 @Input 有关;

    • 或者 @NgModule 配置有问题

    由于 ngForOf 是一个内置指令,因此's analyze what'的问题与 @NgModule 配置有关 .

    首先,我们需要确定此错误的来源 . 从错误消息中很容易看出:

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

    应该很清楚,我们收到了 ChargesComponent 的错误,这是 ChargesModule 的一部分 . 我相信 ChargesModule 声明看起来像:

    charges.module.ts

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

    现在如果你还没有读过我以前的答案Angular 2 Use component from another module我强烈建议你这样做 . 确保您了解如何在其他模块中使用一个组件/指令/管道 . 如果你这样做,那么只需从 SharedModule 导出 CommonModule ,如果你仍有疑问,请继续阅读...

    这里的主要规则是

    Since we need to use ngForOf directive within ChargesComponent template, that is part of ChargesModule, then this directive should be part of directives in transitive ChargesModule.

    这些指令是如何收集的?

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

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

    因此,继续在导入的 @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数组中,并且所有内容都应按预期工作 .

    好问题是

    但是,我不明白为什么只有在将BrowserAnimationsModule从Shared模块移动到Core模块后才会出现此问题 . 你能解释一下吗?

    如果不了解 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 指令并且's why you'收到错误 .

相关问题