Модули, импортированные в AppModule, не видны в разных модулях - PullRequest
1 голос
/ 01 октября 2019

Скажем, это мой 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. Это правильное поведение, или я делаю что-то не так?


Я изменил Imports в AppModule, как предложил @ maryrio7, и теперь это MaterialModule.forRoot(), и я добавил статический метод в MaterialModule, все ещене работает.

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

Ответы [ 3 ]

2 голосов
/ 01 октября 2019

Умм ... Распространенным заблуждением в 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 вместо повторения всех импортов для сторонних модулей.

Например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 голос
/ 01 октября 2019

Лучше использовать SharedModule и затем импортировать его туда, где вы хотите использовать один из его модулей:

Создание общих модулей позволяет вам упорядочить и оптимизировать код. Вы можете поместить часто используемые директивы, каналы и компоненты в один модуль, а затем импортировать только тот модуль, где он вам нужен, в другие части вашего приложения.

@NgModule({
    imports:      [ MaterialModule],
    exports:      [ MaterialModule ]
})
export class SharedModule { }

Теперь вы можете внедрять SharedModule вездеВы хотите, здесь, в HomeModule:

@NgModule({
    imports:      [ SharedModule ] // <-- now you can access MaterialModule
})
export class HomeModule { }
0 голосов
/ 01 октября 2019

Я думаю, что если вы хотите пропустить шаг импорта, вы должны добавить forRoot () к модулю следующим образом:

imports: [
    .....
    MaterialModule.forRoot(),
    ....
  ],

РЕДАКТИРОВАТЬ: попробуйте добавить это в ваш MaterialModule. тс

@NgModule({
  exports: [MaterialModule]
})
export class MaterialModule { }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...