我将更大的应用程序划分为模块(功能模块,核心模块和共享模块)。我正在使用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一起导入。
答案 0 :(得分:7)
如果您遇到类似
的错误无法绑定到'ngForOf',因为它不是已知属性
然后你应该知道它:
与未声明的@Input
;
或者您对@NgModule
配置
由于ngForOf
是一个内置指令,让我们分析一下@NgModule
配置的问题。
首先,我们需要确定此错误的来源。从错误消息中很容易看出:
{{filterColumn | t“):ng:///ChargesModule/ChargesComponent.html@9:22
应该很清楚,ChargesComponent
的{{1}}是ChargesModule
的一部分。我相信ChargesModule
声明如下:
<强> charges.module.ts 强>
@NgModule({
imports: [
SharedModule,
...
],
declarations: [
ChargesComponent,
...
]
})
export class ChargesModule {}
现在,如果您还没有阅读我之前的回答Angular 2 Use component from another module,我强烈建议您这样做。确保您了解如何在其他模块中使用一个组件/指令/管道。如果您这样做,那么只需从CommonModule
导出SharedModule
,如果您仍有疑问,请继续阅读...
这里的主要规则是
由于我们需要在ChargesComponent
模板中使用ngForOf指令,这是ChargesModule的一部分,因此该指令应该是传递ChargesModule中指令的一部分。
如何收集这些指令?
ChargesModule.directives
+
exported directives from imported @NgModules
||
ChargesModule.transitiveModule.directives
乍一看,我们会在ngForOf
声明数组中声明ChargesModule
指令,但ngForOf
已在CommonModule
中声明,并且指令必须只是一个模块的一部分我们做不到。
因此,继续在导入的ngForOf
中查找@NgModules
指令。好吧,我们导入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 {
很明显,如果我们从BrowserAnimationsModule
导出SharedModule
模块,我们也会从CommonModule
导出指令:
SharedModule.transitiveModule.directives
/\
||
BrowserAnimationsModule exports
/\
||
BrowserModule that exports
/\
||
CommonModule
因此,在将BrowserAnimationModule
移至CoreModule
后,您的SharedModule
不再导出ngForOf
指令,这就是您收到错误的原因。