Angular 2 Используйте компонент из другого модуля
У меня есть Angular 2 (версия 2.0.0 - окончательное) приложение, созданное с помощью angular -cli.
Когда я создаю компонент и добавляю его в массив AppModule
declarations, все это хорошо, он работает.
Я решил разделить компоненты, поэтому создал TaskModule
и компонент TaskCard
. Теперь я хочу использовать TaskCard
в одном из компонентов AppModule
(компонент Board
).
AppModule:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { AppComponent } from './app.component';
import { BoardComponent } from './board/board.component';
import { LoginComponent } from './login/login.component';
import { MdButtonModule } from '@angular2-material/button';
import { MdInputModule } from '@angular2-material/input';
import { MdToolbarModule } from '@angular2-material/toolbar';
import { routing, appRoutingProviders} from './app.routing';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
import { UserService } from './services/user/user.service';
import { TaskModule } from './task/task.module';
@NgModule({
declarations: [
AppComponent,
BoardComponent,// I want to use TaskCard in this component
LoginComponent,
PageNotFoundComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
MdButtonModule,
MdInputModule,
MdToolbarModule,
routing,
TaskModule // TaskCard is in this module
],
providers: [UserService],
bootstrap: [AppComponent]
})
export class AppModule { }
TaskModule:
import { NgModule } from '@angular/core';
import { TaskCardComponent } from './task-card/task-card.component';
import { MdCardModule } from '@angular2-material/card';
@NgModule({
declarations: [TaskCardComponent],
imports: [MdCardModule],
providers: []
})
export class TaskModule{}
Весь проект доступен на https://github.com/evgdim/angular2 (папка kanban-board)
Что мне не хватает? Что мне нужно сделать, чтобы использовать TaskCardComponent
в BoardComponent
?
Ответы
Ответ 1
Основное правило здесь таково:
Селекторы, которые применяются во время компиляции шаблона компонента, определяются модулем, который объявляет этот компонент, и транзитивным закрытием экспорта этого модуля.
Итак, попробуйте экспортировать это:
@NgModule({
declarations: [TaskCardComponent],
imports: [MdCardModule],
exports: [TaskCardComponent] <== this line
})
export class TaskModule{}
Что я должен экспортировать?
Экспортируйте декларируемые классы, на которые компоненты в других модулях должны ссылаться в своих шаблонах. Это ваши публичные занятия. Если вы не экспортируете класс, он остается закрытым, видимым только для другого компонента, объявленного в этом модуле.
В тот момент, когда вы создаете новый модуль, ленивый или нет, любой новый модуль и что-то в него объявляете, этот новый модуль находится в чистом состоянии (как сказал Уорд Белл в https://devchat.tv/adv-in-angular/119). -aia-уклонение-общие-подводные камни2)
Angular создает транзитивный модуль для каждого из @NgModule
s.
Этот модуль собирает директивы, которые либо импортированы из другого модуля (если транзитивный модуль импортированного модуля имеет экспортированные директивы), либо объявлены в текущем модуле.
Когда угловая компилирует шаблон, который принадлежит модулю X
используются те директивы, которые были собраны в X.transitiveModule.directives.
compiledTemplate = new CompiledTemplate(
false, compMeta.type, compMeta, ngModule, ngModule.transitiveModule.directives);
https://github.com/angular/angular/blob/4.2.x/packages/compiler/src/jit/compiler.ts#L250-L251
![enter image description here]()
Таким образом, согласно изображению выше
-
YComponent
не может использовать ZComponent
в шаблоне, поскольку directives
массив Transitive module Y
не содержит ZComponent
потому YModule
не импортирован ZModule
которого транзитивно модуль содержит ZComponent
в exportedDirectives
массиве.
-
В шаблоне XComponent
мы можем использовать ZComponent
потому что Transitive module X
имеет массив директив, который содержит ZComponent
потому что XModule
импорта YModule
(YModule
), который экспортирует модуль (ZModule
), который экспортирует директиву ZComponent
-
В шаблоне AppComponent
мы не можем использовать XComponent
потому что AppModule
импортирует XModule
но XModule
не экспортирует XComponent
.
Смотрите также
Ответ 2
Вы должны export
от своего NgModule
:
@NgModule({
declarations: [TaskCardComponent],
exports: [TaskCardComponent],
imports: [MdCardModule],
providers: []
})
export class TaskModule{}
Ответ 3
(Angular 2 - Angular 7)
Компонент может быть объявлен только в одном модуле.
Чтобы использовать компонент из другого модуля, вам нужно выполнить две простые задачи:
- Экспортировать компонент в другой модуль
- Импортировать другой модуль в текущий модуль
1-й модуль:
Имеем компонент (назовем его "ImportantCopmonent"), который мы хотим повторно использовать на странице 2-го модуля.
@NgModule({
declarations: [
FirstPage,
ImportantCopmonent // <-- Enable using the component html tag in current module
],
imports: [
IonicPageModule.forChild(NotImportantPage),
TranslateModule.forChild(),
],
exports: [
FirstPage,
ImportantCopmonent // <--- Enable using the component in other modules
]
})
export class FirstPageModule { }
2-й модуль:
Повторно использует "ImportantCopmonent", импортируя FirstPageModule
@NgModule({
declarations: [
SecondPage,
Example2ndComponent,
Example3rdComponent
],
imports: [
IonicPageModule.forChild(SecondPage),
TranslateModule.forChild(),
FirstPageModule // <--- this Imports the source module, with its exports
],
exports: [
SecondPage,
]
})
export class SecondPageModule { }
Ответ 4
Обратите внимание, что для создания так называемого "функционального модуля" вам нужно импортировать CommonModule
внутри него. Итак, код инициализации вашего модуля будет выглядеть следующим образом:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { TaskCardComponent } from './task-card/task-card.component';
import { MdCardModule } from '@angular2-material/card';
@NgModule({
imports: [
CommonModule,
MdCardModule
],
declarations: [
TaskCardComponent
],
exports: [
TaskCardComponent
]
})
export class TaskModule { }
Дополнительная информация доступна здесь: https://angular.io/guide/ngmodule#create-the-feature-module
Ответ 5
Независимо от того, что вы хотите использовать из другого модуля, просто поместите его в массив export.
Как это -
@NgModule({
declarations: [TaskCardComponent],
exports: [TaskCardComponent],
imports: [MdCardModule]
})
Ответ 6
РЕШЕНО, КАК ИСПОЛЬЗОВАТЬ КОМПОНЕНТ, ЗАЯВЛЕННЫЙ В МОДУЛЕ В ДРУГОМ МОДУЛЕ.
На основании объяснения Ройи Намира (Большое спасибо). Отсутствует часть для повторного использования компонента, объявленного в модуле, в любом другом модуле, пока используется отложенная загрузка.
1-й: экспортируйте компонент в модуль, который содержит его:
@NgModule({
declarations: [TaskCardComponent],
imports: [MdCardModule],
exports: [TaskCardComponent] <== this line
})
export class TaskModule{}
2-й: в модуле, где вы хотите использовать TaskCardComponent:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MdCardModule } from '@angular2-material/card';
@NgModule({
imports: [
CommonModule,
MdCardModule
],
providers: [],
exports:[ MdCardModule ] <== this line
})
export class TaskModule{}
Таким образом, второй модуль импортирует первый модуль, который импортирует и экспортирует компонент.
Когда мы импортируем модуль во второй модуль, нам нужно экспортировать его снова. Теперь мы можем использовать первый компонент во втором модуле.
Ответ 7
Один большой и отличный подход заключается в загрузке модуля из NgModuleFactory
Вы можете загрузить модуль внутри другого модуля, вызвав это:
constructor(private loader: NgModuleFactoryLoader, private injector: Injector) {}
loadModule(path: string) {
this.loader.load(path).then((moduleFactory: NgModuleFactory<any>) => {
const entryComponent = (<any>moduleFactory.moduleType).entry;
const moduleRef = moduleFactory.create(this.injector);
const compFactory = moduleRef.componentFactoryResolver.resolveComponentFactory(entryComponent);
this.lazyOutlet.createComponent(compFactory);
});
}
Я получил это отсюда.
Ответ 8
@yurzui у вас есть правильное решение и спасибо за объяснение.
У меня была проблема и эта строка:
экспорт: [Компонент] решил.