Angular2マテリアルダイアログには問題があります-@ NgModule.entryComponentsに追加しましたか?


232

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

回答:


604

動的に作成されたコンポーネントをentryComponents内部に追加する必要があります@NgModule

@NgModule({
  declarations: [
    AppComponent,
    LoginComponent,
    DashboardComponent,
    HomeComponent,
    DialogResultExampleDialog        
  ],
  entryComponents: [DialogResultExampleDialog]

注:いくつかのケースではentryComponents下の怠惰なロードされたモジュールの回避策は、あなたの中に入れて、動作しませんapp.module(ルート)


9
ありがとう!これをどこでも探していました。私の特定のケースでは、物事を機能させるためにコンポーネントをに追加する必要ありましたdeclarations
Jasdeep Khalsa

95
私がNgModuleに頭を悩ますように感じるたびに、このようなものが表示され、このフレームワークが非常に複雑である必要があるかどうか疑問に思われます。少なくとも、エラーメッセージは役に立ちます。
daddywoodland 2017

3
すでにそこにある場合はどうなりますか?なぜ彼らは離れていると言うのですか?
Sam Alexander

1
@SamAlexanderあなたの質問はあなたが感謝するだろうが、大まかな推測をするので本当に広いです。遅延ロードされたモジュール内でそれらを使用しますか?
eko

1
遅延ロードされたモジュールのダイアログは2.0.0-beta.2以降で機能します
charlie_pl

53

entryComponents以下で使用する必要があります@NgModule

これは、を使用して追加される動的に追加されるコンポーネント用ViewContainerRef.createComponent()です。それらをentryComponentsに追加すると、オフラインテンプレートコンパイラにそれらをコンパイルしてファクトリを作成するように指示します。

はDOMにルーティングされたコンポーネントを追加するentryComponentsためにrouter-outletも使用さViewContainerRef.createComponent()れるため、ルート構成に登録されたコンポーネントも自動的に追加されます。

したがって、コードは次のようになります

@NgModule({
  declarations: [
    AppComponent,
    LoginComponent,
    DashboardComponent,
    HomeComponent,
    DialogResultExampleDialog        
  ],
  entryComponents: [DialogResultExampleDialog]

うーん...他の点では同じである2つのダイアログがありましたが、1つはそれを指すテストルートがありました。私はそのテストルートを削除し、確かに...ルーティングは私を「助けて」くれました。> :(
トム

@Sunil Garg別の問題があります。ダイアログは表示されますが、1秒以内に自動的に閉じます。私を助けてください。
Priyanka C

10

これは動的コンポーネントであり、あなたがそれをentryComponentsunderに追加しなかったために起こります@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
})

3
私と同じケースで動作しません:表示:エラー:DialogConfirmComponentのコンポーネントファクトリが見つかりません。@ NgModule.entryComponentsに追加しましたか?何か案が?
Nam Le

ngAfterViewInitに挿入する必要があります(@ angular / coreから)
Patryk Panek 2018年

8

MatDialogサービス内で使用しようとしている場合-それ'PopupService'を呼び出しましょう。そのサービスは次のようにモジュールで定義されています。

@Injectable({ providedIn: 'root' })

その後、機能しない場合があります。私は遅延読み込みを使用していますが、それが関連しているかどうかはわかりません。

必ず:

  • PopupServiceを使用して、ダイアログを開くコンポーネントに直接提供します[ provide: PopupService ]。これによりMatDialog、コンポーネント内のインスタンスを(DIで)使用できます。openこの場合、コンポーネントの呼び出しはダイアログコンポーネントと同じモジュール内にある必要があると思います。
  • ダイアログコンポーネントをapp.moduleに移動します(他のいくつかの回答が言っているように)
  • matDialogサービスを呼び出すときに参照を渡します。

MatDialogがコンポーネントをピギーバックする必要があるため、問題が壊れいるというのが私の混乱した答えです。providedIn: 'root'


これが起こります!確かに、entrycomponentではなく間違ったエラーメッセージを表示する代わりに、提供するサービスを追加してください!
ティビ

私にも同じことが起こっていますが、この答えからは理解できませんでした。どの点が解決策ですか?それとも3つすべてが必要ですか?
coding_idiot

同じ問題
MJVM

4

遅延読み込みの場合、遅延読み込みモジュールにMatDialogModuleをインポートするだけです。次に、このモジュールは、独自のインポートされたMatDialogModuleを使用してエントリコンポーネントをレンダリングできます。

@NgModule({
  imports:[
    MatDialogModule
  ],
  declarations: [
    AppComponent,
    LoginComponent,
    DashboardComponent,
    HomeComponent,
    DialogResultExampleDialog        
  ],
  entryComponents: [DialogResultExampleDialog]

1

マテリアルダイアログの統合は可能です、そのような些細な機能の複雑さはかなり高いことがわかりました。重要な機能を実現しようとすると、コードはさらに複雑になります。

そのため、私は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のドキュメントは、理解しやすく、非常に正確です。


動的に作成されたコンポーネントが不要になるまで、トピックスターターの問題に直面することはありません。動的コンポーネントの作成を使用するダイアログサービスを(primengを使用して)作成しようとすると、まったく同じ問題に直面します...
DicBrus

1

docsでentryComponents指定されているように、に追加する必要があります。

@NgModule({
  imports: [
    // ...
  ],
  entryComponents: [
    DialogInvokingComponent, 
    DialogResultExampleDialog
  ],
  declarations: [
    DialogInvokingComponent,   
    DialogResultExampleDialog
  ],
  // ...
})

以下はダイアログがとして定義されているアプリモジュールファイルの完全な例ですentryComponents


0

私のようで、このスレッドを見つめながら、「コンポーネントを追加しようとしているのではなく、ガード/サービス/パイプなどを追加しようとしている」と考えている場合 次に、ルーティングパスに間違ったタイプを追加したことが問題である可能性があります。それが私がしたことです。canActivate:セクションではなく、パスのcomponent:セクションに誤ってガードを追加しました。IDEのオートコンプリートは大好きですが、少し遅くして注意を払う必要があります。どうしても見つからない場合は、不満のある名前をグローバルに検索し、すべての使用法を調べて、名前を間違えていないことを確認してください。


0

私の場合、コンポーネントを宣言とentryComponentsに追加すると、同じエラーが発生しました。インポートにMatDialogModuleを追加する必要もありました。


0

誰かがサービスからDialogを呼び出す必要がある場合は、ここで問題を解決する方法です。上記の回答のいくつかに同意します。私の回答は、誰かが問題に直面した場合にサービスのダイアログを呼び出すためのものです。

DialogServiceなどのサービスを作成し、ダイアログ関数をサービス内に移動して、以下のコードのように、呼び出すコンポーネントにダイアログサービスを追加します。

 @Component({
  selector: "app-newsfeed",
  templateUrl: "./abc.component.html",
  styleUrls: ["./abc.component.css",],
  providers:[DialogService]
})

そうしないと、エラーが発生します

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.