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
に追加する必要があります。
@NgModule({
declarations: [
AppComponent,
LoginComponent,
DashboardComponent,
HomeComponent,
DialogResultExampleDialog
],
entryComponents: [DialogResultExampleDialog]
注: 場合によっては レイジーロードされたモジュールの下のentryComponents
は回避策としてそれらをあなたのapp.module
(root)に入れてしまうのでうまくいきません。
@NgModule
の下でentryComponents
を使用する必要があります。
これは、ViewContainerRef.createComponent()
を使用して追加された動的に追加されたコンポーネント用です。それらをentryComponentsに追加すると、オフラインテンプレートコンパイラはそれらをコンパイルしてそれらのファクトリを作成するように指示されます。
router-outlet
はルーティングされたコンポーネントをDOMに追加するためにViewContainerRef.createComponent()
も使用するので、ルート設定に登録されたコンポーネントはentryComponents
にも自動的に追加されます。
だからあなたのコードはのようになります
@NgModule({
declarations: [
AppComponent,
LoginComponent,
DashboardComponent,
HomeComponent,
DialogResultExampleDialog
],
entryComponents: [DialogResultExampleDialog]
これは 動的コンポーネント であり、@NgModule
の下のentryComponents
に追加しなかったために発生しています。
単にそれをそこに追加します。
@NgModule({
/* ----------------- */
entryComponents: [ DialogResultExampleDialog ] // <---- Add it here
Angularチーム がentryComponents
についてどのように語っているかを見てください。
entryComponents?: Array<Type<any>|any[]>
このモジュールが定義されているときにコンパイルされるべきコンポーネントのリストを指定します。ここにリストされた各コンポーネントに対して、AngularはComponentFactoryを作成し、それをComponentFactoryResolverに格納します。
また、これはentryComponents
...を含む@NgModule
のメソッドのリストです。
ご覧のとおり、コンポーネントの配列を受け入れる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
})
あなたがサービスの中でMatDialog
を使用しようとしているなら - それを'PopupService'
と呼びましょう、そしてそのサービスは次のようにモジュールで定義されます:
@Injectable({ providedIn: 'root' })
それからそれは働かないかもしれません。遅延読み込みを使用していますが、それが関連性があるかどうかはわかりません。
必ず:
[ provide: PopupService ]
を使用して、PopupService
をダイアログを開くコンポーネントに直接指定します。これにより、コンポーネント内でMatDialog
インスタンスを(DIと共に)使用することができます。この場合、open
を呼び出すコンポーネントはダイアログコンポーネントと同じモジュール内にある必要があると思います。matDialog
の参照を渡します。すみません答えを言ってください、 MatDialogがコンポーネントをピギーバックする必要があるため、問題を起こしているのはprovidedIn: 'root'
です。
材料対話を統合することは可能ですが、そのようなささいな機能の複雑さはかなり高いことがわかりました。あなたが重要な機能を達成しようとしているならば、コードはより複雑になります。
そのため、 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ドキュメント に従うのは簡単で、非常に正確です。
私の場合は、宣言とentryComponentsに自分のコンポーネントを追加しても同じエラーになりました。また、インポートにMatDialogModuleを追加する必要がありました。
遅延ロードの場合は、遅延ロードされたモジュールに MatDialogModule をインポートするだけです。それからこのモジュールは自身のインポートされた MatDialogModule でエントリコンポーネントをレンダリングすることができるでしょう:
@NgModule({
imports:[
MatDialogModule
],
declarations: [
AppComponent,
LoginComponent,
DashboardComponent,
HomeComponent,
DialogResultExampleDialog
],
entryComponents: [DialogResultExampleDialog]
あなたが私のようで、「しかし、私はコンポーネントを追加しようとしているのではなく、私はガード/サービス/パイプなどを追加しようとしています」と考えてこのスレッドを見つめています。それから問題はあなたがルーティングパスに間違ったタイプを追加したということです。それが私がしたことです。 canActivate:セクションではなく、パスのcomponent:セクションに誤ってガードを追加しました。 IDEオートコンプリートが大好きですが、少し遅くして注意を払う必要があります。絶対に見つけられない場合は、文句を言っている名前をグローバルに検索し、すべての用法を調べて、名前が入力されていないことを確認します。