让我们说这是我的AppModule:
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
MaterialModule,
HomeModule
],
exports: [
MaterialModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
如您所见,我在MaterialModule
上声明了HomeModule
,然后导出了MaterialModule
。
但是仍然在HomeModule
中,我无法使用MaterialModule
中的组件,错误:
1. If 'mat-icon' is an Angular component, then verify that it is part of this module.
2. If 'mat-icon' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.
因此,我不得不再次在MaterialModule
中导入HomeModule
。这是正确的行为还是我做错了什么?
我按照@ maryrio7的建议更改了AppModule
中的Imports,现在是MaterialModule.forRoot()
,并且向MaterialModule
添加了静态方法,仍然无法使用。
@NgModule({
imports: [
MatButtonModule,
MatCardModule,
MatIconModule,
],
exports: [
MatButtonModule,
MatCardModule,
MatIconModule
]
})
export class MaterialModule {
static forRoot(): ModuleWithProviders {
return {
ngModule: MaterialModule,
providers: []
};
}
}
答案 0 :(得分:2)
嗯... Angular中的一个常见误解是在父模块(即您的示例中为AppModule)中导入模块会创建模块的层次结构。因此,人们认为AppModule的子模块(即HomeModule)应该也继承父模块的导入模块。
但是,事实并非如此。模块不会继承对在父模块中声明的模块的访问。将模块想象成一个盒子。一个盒子将只包含您放入其中的所有内容。
现在,如果您有3个盒子,即盒子A,盒子M和盒子H。如果您没有将盒子M放在盒子H内,为什么盒子H包含属于盒子M的东西?
类似地,如果您将盒子M和盒子H放在盒子A内。现在,盒子A肯定会同时包含盒子M和盒子H中的所有东西,不是吗?
现在,将术语“盒子”切换为模块,将A切换为AppModule,将M切换为MaterialModule,将H切换为HomeModule。现在更有意义了吗?
要在Angular应用程序中进一步强调这一点,这就是为什么在生成新模块时会在新模块中自动导入CommonModule的原因。 CommonModule是BrowserModule的“较小”版本,包含组件中常用的NgIf,NgFor等指令。因为在新模块中,BrowserModule不会自动继承到其中-ngIf,ngFor等将不起作用。您可以通过删除CommonModule进行测试,看看是否可以使用ngFor,ngIf等。
您可以通过创建SharedModule来导入所有第三方lib的模块来轻松解决此问题。即导入MaterialModule,然后将其导出。
然后,所有(延迟加载的)功能模块都必须导入一个SharedModule,而不必重复对第三方模块的所有导入。
例如共享模块
@NgModule({
imports:[
CommonModule, FormsModule, ReactiveFormsModule, MaterialModule,
//... {other modules that will be shared between modules} ...,
],
exports:[
CommonModule, FormsModule, ReactiveFormsModule, MaterialModule,
//... {other modules that will be shared between modules} ...,
]
})
答案 1 :(得分:1)
最好使用SharedModule,然后将其导入到要使用其模块之一的位置:
创建共享模块可以使您组织和简化代码。您可以将常用的指令,管道和组件放入一个模块,然后在需要的其他位置将其仅导入应用程序的其他部分。
@NgModule({
imports: [ MaterialModule],
exports: [ MaterialModule ]
})
export class SharedModule { }
现在,您可以在HomeModule中的任意位置注入SharedModule:
@NgModule({
imports: [ SharedModule ] // <-- now you can access MaterialModule
})
export class HomeModule { }
答案 2 :(得分:0)
我认为如果要跳过导入步骤,则必须将forRoot()添加到模块中,如下所示:
imports: [
.....
MaterialModule.forRoot(),
....
],
编辑: 尝试将其添加到您的 MaterialModule.ts
@NgModule({
exports: [MaterialModule]
})
export class MaterialModule { }