AppModule 中导入的模块在不同模块中不可见

DiP*_*Pix 5 angular

假设这是我的 AppModule:

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    MaterialModule,
    HomeModule
  ],
  exports: [
    MaterialModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
Run Code Online (Sandbox Code Playgroud)

正如你所看到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. 
Run Code Online (Sandbox Code Playgroud)

所以我被迫MaterialModule再次导入HomeModule。这是正确的行为还是我做错了什么?


AppModule我按照@maryrio7的建议更改了导入,现在是MaterialModule.forRoot(),并且我添加了静态方法MaterialModule,但仍然不起作用。

@NgModule({
    imports: [
        MatButtonModule,
        MatCardModule,
        MatIconModule,
    ],
    exports: [
        MatButtonModule,
        MatCardModule,
        MatIconModule
    ]
})
export class MaterialModule {
    static forRoot(): ModuleWithProviders {
        return {
            ngModule: MaterialModule,
            providers: []
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

ter*_*rtz 10

嗯... Angular 中的一个常见误解是在父模块(即在您的示例中为 AppModule)中导入模块会创建模块层次结构。因此,人们认为AppModule的子模块(即HomeModule)也应该继承父模块的导入模块。

然而,事实并非如此。模块不会继承对父模块中声明的模块的访问权限。将模块想象成一个盒子。盒子只能容纳您放入其中的任何东西。

现在,如果你有 3 个盒子,盒子 A、盒子 M 和盒子 H。如果你没有将盒子 M 放入盒子 H 中,为什么盒子 H 会包含属于盒子 M 的东西?

同样,如果您将盒子 M 和盒子 H 放入盒子 A 中。现在,盒子 A 肯定会包含盒子 M 和盒子 H 中的所有东西,不是吗?

现在,将术语“box”切换为模块,将 A 切换为 AppModule,M 切换为 MaterialModule,H 切换为 HomeModule。现在更有意义了吗?

为了在 Angular 应用程序中进一步强调这一点,这就是为什么当您生成新模块时,CommonModule 会自动导入到新模块中。CommonModule 是 BrowserModule 的“较小”版本,包含组件中常用的 NgIf、NgFor 等指令。因为在新模块中,BrowserModule 不会自动继承到其中 - ngIf、ngFor 等不起作用。您可以通过删除 CommonModule 来测试这一点,看看是否可以使用 ngFor、ngIf 等。


您可以通过创建 SharedModule 来导入所有第三方库的模块来轻松解决此问题。即导入MaterialModule,然后将其导出。

然后,您的所有(延迟加载)功能模块都必须导入一个 SharedModule,而不是重复对第 3 方模块进行所有导入。

例如共享模块

@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} ...,
    ]
})
Run Code Online (Sandbox Code Playgroud)