web-dev-qa-db-ja.com

Angular 2マテリアルダイアログに問題があります - @ 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
203
Tampa

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

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

注: 場合によっては レイジーロードされたモジュールの下のentryComponentsは回避策としてそれらをあなたのapp.module(root)に入れてしまうのでうまくいきません。

525
eko

@NgModuleの下でentryComponentsを使用する必要があります。

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

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

だからあなたのコードはのようになります

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

これは 動的コンポーネント であり、@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
})
9
Alireza

あなたがサービスの中でMatDialogを使用しようとしているなら - それを'PopupService'と呼びましょう、そしてそのサービスは次のようにモジュールで定義されます:

@Injectable({ providedIn: 'root' })

それからそれは働かないかもしれません。遅延読み込みを使用していますが、それが関連性があるかどうかはわかりません。

必ず:

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

すみません答えを言ってください、 MatDialogがコンポーネントをピギーバックする必要があるため、問題を起こしているのはprovidedIn: 'root'です。

3
Simon_Weaver

材料対話を統合することは可能ですが、そのようなささいな機能の複雑さはかなり高いことがわかりました。あなたが重要な機能を達成しようとしているならば、コードはより複雑になります。

そのため、 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ドキュメント に従うのは簡単で、非常に正確です。

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

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

これは 完全な例ですentryComponentsとして定義されたダイアログを含むアプリモジュールファイルの場合です。

0
yuval.bl

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

0
Dela

遅延ロードの場合は、遅延ロードされたモジュールに MatDialogModule をインポートするだけです。それからこのモジュールは自身のインポートされた MatDialogModule でエントリコンポーネントをレンダリングすることができるでしょう:

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

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

0
LeftOnTheMoon