Angular2 В диалоге материалов есть проблемы. Вы добавили его в @NgModule.entryComponents?
Я пытаюсь следовать документам на https://material.angular.io/components/component/dialog, но не могу понять, почему у него есть проблема ниже?
Я добавил ниже на моем компоненте:
@Component({
selector: 'dialog-result-example-dialog',
templateUrl: './dialog-result-example-dialog.html',
})
export class DialogResultExampleDialog {
constructor(public dialogRef: MdDialogRef<DialogResultExampleDialog>) {}
}
В моем модуле я добавил
import { HomeComponent,DialogResultExampleDialog } from './home/home.component';
@NgModule({
declarations: [
AppComponent,
LoginComponent,
DashboardComponent,
HomeComponent,
DialogResultExampleDialog
],
// ...
Все же я получаю эту ошибку....
EXCEPTION: Error in ./HomeComponent class HomeComponent - inline template:53:0 caused by: No component factory found for DialogResultExampleDialog. Did you add it to @NgModule.entryComponents?
ErrorHandler.handleError @ error_handler.js:50
next @ application_ref.js:346
schedulerFn @ async.js:91
SafeSubscriber.__tryOrUnsub @ Subscriber.js:223
SafeSubscriber.next @ Subscriber.js:172
Subscriber._next @ Subscriber.js:125
Subscriber.next @ Subscriber.js:89
Subject.next @ Subject.js:55
EventEmitter.emit @ async.js:77
NgZone.triggerError @ ng_zone.js:329
onHandleError @ ng_zone.js:290
ZoneDelegate.handleError @ zone.js:246
Zone.runTask @ zone.js:154
ZoneTask.invoke @ zone.js:345
error_handler.js:52 ORIGINAL EXCEPTION: No component factory found for DialogResultExampleDialog. Did you add it to @NgModule.entryComponents?
ErrorHandler.handleError @ error_handler.js:52
next @ application_ref.js:346
schedulerFn @ async.js:91
SafeSubscriber.__tryOrUnsub @ Subscriber.js:223
SafeSubscriber.next @ Subscriber.js:172
Subscriber._next @ Subscriber.js:125
Subscriber.next @ Subscriber.js:89
Subject.next @ Subject.js:55
EventEmitter.emit @ async.js:77
NgZone.triggerError @ ng_zone.js:329
onHandleError @ ng_zone.js:290
ZoneDelegate.handleError @ zone.js:246
Zone.runTask @ zone.js:154
ZoneTask.invoke @ zone.js:345
Ответы
Ответ 1
Вам нужно добавить динамически созданные компоненты в entryComponents
внутри вашего @NgModule
@NgModule({
declarations: [
AppComponent,
LoginComponent,
DashboardComponent,
HomeComponent,
DialogResultExampleDialog
],
entryComponents: [DialogResultExampleDialog]
Примечание: в некоторых случаях entryComponents
под лениво загруженными модулями не будут работать, так как обходной путь помещает их в ваш app.module
(root)
Ответ 2
Вам нужно использовать entryComponents
под @NgModule
.
Это для динамически добавляемых компонентов, которые добавляются с использованием ViewContainerRef.createComponent()
. Добавление их в entryComponents позволяет автономному компилятору шаблонов скомпилировать их и создать для них фабрики.
Компоненты, зарегистрированные в конфигурациях маршрутов, также автоматически добавляются в entryComponents
потому что router-outlet
также использует ViewContainerRef.createComponent()
для добавления маршрутизируемых компонентов в DOM.
Так что ваш код будет похож
@NgModule({
declarations: [
AppComponent,
LoginComponent,
DashboardComponent,
HomeComponent,
DialogResultExampleDialog
],
entryComponents: [DialogResultExampleDialog]
Ответ 3
Это происходит потому, что это динамический компонент, и вы не добавили его в entryComponents
в @NgModule
.
Просто добавьте это туда:
@NgModule({
/* ----------------- */
entryComponents: [ DialogResultExampleDialog ] // <---- Add it here
Посмотрите, как команда Angular говорит о entryComponents
:
entryComponents?: Array<Type<any>|any[]>
Определяет список компонентов, которые должны быть скомпилированы при определении этого модуля. Для каждого компонента, указанного здесь, Angular создаст ComponentFactory и сохранит его в ComponentFactoryResolver.
Кроме того, это список методов @NgModule
включая entryComponents
...
Как видите, все они являются необязательными (посмотрите на вопросительные знаки), включая entryComponents
которые принимают массив компонентов:
@NgModule({
providers?: Provider[]
declarations?: Array<Type<any>|any[]>
imports?: Array<Type<any>|ModuleWithProviders|any[]>
exports?: Array<Type<any>|any[]>
entryComponents?: Array<Type<any>|any[]>
bootstrap?: Array<Type<any>|any[]>
schemas?: Array<SchemaMetadata|any[]>
id?: string
})
Ответ 4
Если вы пытаетесь использовать MatDialog
внутри службы - позвольте назвать его 'PopupService'
и эта служба определена в модуле с:
@Injectable({ providedIn: 'root' })
тогда это может не сработать. Я использую ленивую загрузку, но не уверен, что это актуально или нет.
Ты должен:
- Предоставьте ваш
PopupService
непосредственно компоненту, открывающему ваше диалоговое окно - с помощью [ provide: PopupService ]
. Это позволяет ему использовать (с DI) экземпляр MatDialog
в компоненте. Я думаю, что компонент, вызывающий open
должен находиться в том же модуле, что и компонент диалога в этом случае. - Переместите компонент диалога вверх в ваш app.module (как сказали некоторые другие ответы)
- Передайте ссылку на
matDialog
когда вы звоните в свой сервис.
Извините за мой беспорядочный ответ, суть в том, что он providedIn: 'root'
который ломает вещи, потому что MatDialog должен отодвинуть компонент.
Ответ 5
Хотя интеграция материалов диалога возможна, я обнаружил, что сложность такой тривиальной функции довольно высока. Код становится более сложным, если вы пытаетесь достичь нетривиальных функций.
По этой причине я использовал PrimeNG Dialog, который я нашел довольно простым в использовании:
m-dialog.component.html
:
<p-dialog header="Title">
Content
</p-dialog>
m-dialog.component.ts
:
@Component({
selector: 'm-dialog',
templateUrl: 'm-dialog.component.html',
styleUrls: ['./m-dialog.component.css']
})
export class MDialogComponent {
// dialog logic here
}
m-dialog.module.ts
:
import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common";
import { DialogModule } from "primeng/primeng";
import { FormsModule } from "@angular/forms";
@NgModule({
imports: [
CommonModule,
FormsModule,
DialogModule
],
exports: [
MDialogComponent,
],
declarations: [
MDialogComponent
]
})
export class MDialogModule {}
Просто добавьте ваш диалог в ваш компонент HTML:
<m-dialog [isVisible]="true"> </m-dialog>
PrimeNG Документация PrimeFaces проста в использовании и очень точна.
Ответ 6
Если вы похожи на меня и смотрите на эту тему, думая: "Но я не пытаюсь добавить компонент, я пытаюсь добавить охрану/сервис/канал и т.д." то проблема скорее всего в том, что вы добавили неверный тип в маршрут маршрутизации. Это то, что я сделал. Я случайно добавил охрану в компонент: раздел пути вместо секции canActivate:. Я люблю автозаполнение IDE, но вам нужно немного замедлить и обратить внимание. Если вы абсолютно не можете его найти, выполните глобальный поиск имени, на которое он жалуется, и посмотрите на каждое использование, чтобы убедиться, что вы не проскальзывали с именем.
Ответ 7
В моем случае я добавил свой компонент в объявления и элементы entryComponents и получил те же ошибки. Мне также нужно было добавить MatDialogModule для импорта.
Ответ 8
исправлено добавлением этого компонента в начальную загрузку: [AppComponent, newComponent] в app.module.ts
Ответ 9
В случае отложенной загрузки, вам просто нужно импортировать MatDialogModule в загруженный модуль с отложенной загрузкой. Затем этот модуль сможет визуализировать компонент ввода с собственным импортированным MatDialogModule:
@NgModule({
imports:[
MatDialogModule
],
declarations: [
AppComponent,
LoginComponent,
DashboardComponent,
HomeComponent,
DialogResultExampleDialog
],
entryComponents: [DialogResultExampleDialog]
Ответ 10
Вы должны добавить его в entryComponents
, как указано в документации.
@NgModule({
imports: [
// ...
],
entryComponents: [
DialogInvokingComponent,
DialogResultExampleDialog
],
declarations: [
DialogInvokingComponent,
DialogResultExampleDialog
],
// ...
})
Вот полный пример файла модуля приложения с диалогом, определенным как entryComponents
.