我试图在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
你需要在@NgModule下使用entryComponents。
这适用于使用ViewContainerRef.createComponent()动态添加的组件。将它们添加到entryComponents告诉脱机模板编译器编译它们并为它们创建工厂。
在路由配置中注册的组件也会自动添加到entryComponents中,因为路由器出口也使用ViewContainerRef.createComponent()将路由组件添加到DOM中。
所以你的代码就像
@NgModule({
declarations: [
AppComponent,
LoginComponent,
DashboardComponent,
HomeComponent,
DialogResultExampleDialog
],
entryComponents: [DialogResultExampleDialog]
你需要在@NgModule下使用entryComponents。
这适用于使用ViewContainerRef.createComponent()动态添加的组件。将它们添加到entryComponents告诉脱机模板编译器编译它们并为它们创建工厂。
在路由配置中注册的组件也会自动添加到entryComponents中,因为路由器出口也使用ViewContainerRef.createComponent()将路由组件添加到DOM中。
所以你的代码就像
@NgModule({
declarations: [
AppComponent,
LoginComponent,
DashboardComponent,
HomeComponent,
DialogResultExampleDialog
],
entryComponents: [DialogResultExampleDialog]
如果你试图在服务中使用MatDialog -让我们称其为“PopupService”,该服务定义在一个模块中:
@Injectable({ providedIn: 'root' })
那么它可能不会起作用。我正在使用惰性加载,但不确定这是否相关。
你必须:
使用[提供:PopupService]直接向打开对话框的组件提供PopupService。这允许它在组件中使用(DI) MatDialog实例。我认为在这个实例中调用open的组件需要与dialog组件在同一个模块中。
将对话框组件移到app.module中(就像其他答案所说的那样)
在调用服务时传递matDialog的引用。
请原谅我的混乱的答案,重点是它的providedIn: 'root'是打破东西,因为MatDialog需要从一个组件。
Angular 9.0.0 <
从9.0.0版本的Ivy开始,entryComponents属性就不再需要了。参见弃用指南。
Angular 9.0.0 >
你需要将动态创建的组件添加到@NgModule中的entryComponents中
@NgModule({
declarations: [
AppComponent,
LoginComponent,
DashboardComponent,
HomeComponent,
DialogResultExampleDialog
],
entryComponents: [DialogResultExampleDialog]
注意:在某些情况下,惰性加载模块下的entryComponents将不起作用,作为一种变通方法,将它们放在你的app.module(根)中
这是因为这是一个动态组件,你没有将它添加到@NgModule下的entryComponents中。
简单地添加到这里:
@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
})