2017-10-22 9 views
1

この例で示すように動的子コンポーネントを持つコンポーネントを作成しようとしています:Angular Dynamic Component Loader。まあ、それは優しい簡単です、私はそれを実装しています。私の現在のケースでは、MatDialogクラスでコンポーネントを動的にロードしようとしています。リファレンス:Angular Material Dialog。ここまでは順調ですね。私の動的コンポーネントクラス:角4 - EventEmitterなしの子コンポーネントのイベントへのアクセス

@Component({ 
    selector: 'dynamic-dialog', 
    template: `<div class="ad-banner"> 
      <h3>{{title}}</h3> 
      <ng-template dialog-host></ng-template> 
      </div>` 
    }) 
export class DialogComponent<T> 
{ 

@ViewChild(DialogDirective) dialogHost: DialogDirective; 
title:string; 

constructor(
    public dialogRef: MatDialogRef<T>, @Inject(MAT_DIALOG_DATA) public      
    data: any, component:T, 
    private _toast: Toaster, private apiBase: apiBase, type: { new():     
    T;}, 
    private componentFactoryResolver: ComponentFactoryResolver 
    ){ 
     let componentFactory = this.componentFactoryResolver.resolveComponentFactory<Component>(type); 
     let viewContainerRef = this.dialogHost.viewContainerRef; 
     viewContainerRef.clear(); 
     let componentRef = viewContainerRef.createComponent(componentFactory); 
     this.title = data.title; 
    } 
} 

私のダイアログのサービス:

openGenericDialog<T>(t:T, data:{}, 
     type: { new(): T ;}, 
     height:string, 
     width:string, 
     callback 
     ): MatDialogRef<DialogComponent<T>> { 
    let dialogRef = this.dialog.open(DialogComponent, { 
       width: width, 
       height:height, 
       data: data 
      }); 

    dialogRef.afterClosed().subscribe(result => { 
     //when you close the box, it will return the control right here 
     if(callback){ 
      callback(result); 
     } 
     //write the closed event right here. 
    }); 

    return dialogRef; 
} 

は今、我々がダイアログで動的に任意のコンポーネントをロードした場合、それはダイアログを閉じるには、ボタンを持っているであろうことは明らかです。さて、私はこれを閉じるためにEventEmitterを使用できることを理解しています。私は、イベントエミッターを宣言して、ジェネリッククラスでイベントハンドラーを作成しようとします。しかし、それは私がそのダイアログボックス内に表示されている可能性のある各コンポーネントにOutPutイベントを書き込む必要があります。子クラスのイベントを直接取り込む方法はありますか?私はAngularで実際には良くないので、これを記述または実装する正しい方法を見つけることができません。私が望むのは、ダイアログサービスのclose関数を呼び出すChildComponent内で呼び出すことができる関数です。それは直感的ですか?そうでない場合は、私に詳細を追加することができますのでお知らせください。混乱してもごめんなさい。上記はコンパイル可能なコードではなく、依然としてWIPであることに注意してください。ここでは私が何をしようとしているかを示すためにここに掲載されています。

更新:私は注入されたサービスを使用して修正しました。以前は、複数のダイアログが存在する可能性があるため、アクティブなダイアログボックスの参照を混乱させる可能性があるため、サービスを注入するのは快適ではありませんでした。だから私は簡単な回避策を行い、ダイアログボックスの参照を含むキーを辞書に追加しました。このようにして、特定のキーを使用してダイアログボックスを制御することができます。以下の私がした変更です:

ダイアログサービス:

closeDialog(key:string, data:any){ 
    let dialogRef = this.dialogs[key]; 

    if(dialogRef){ 
     dialogRef.close(data); 
    } 
} 

スウィート:ボックスを閉じる

openGenericDialog<T>(t:T, data:{}, 
     type: { new(): T ;}, 
     height:string, 
     width:string, 
     key:string, <=== added a unique key to be associated with the dialog 
     callback 
     ): MatDialogRef<DialogComponent<T>> { 
    let dialogRef = this.dialog.open(DialogComponent, { 
       width: width, 
       height:height, 
       data: data 
      }); 
      //add it in the dictionary 
      this.dialogs[key] = dialogRef; <== storing the object in a dictionary using the unique key. 

    dialogRef.afterClosed().subscribe(result => { 
     //when you close the box, it will return the control right here 

     //remove from the dialog collection 

     if(this.dialogs[key]){ 
      this.dialogs[key] = ''; 
     } 

     if(callback){ 
      callback(result); 
     } 
     //write the closed event right here. 
    }); 

    return dialogRef; 
} 

@Injectable() 
export class DialogService{ 

dialogs:any={}; 

constructor(public dialog: MatDialog) {} 

は、辞書内の参照を保存するには!助けてくれてありがとう

答えて

2

親コンポーネントにサービスを提供するか、動的に追加された子にサービスを提供して通信することもできます。

代わりにカスタムイベントを発生する方法の詳細については@HostListener('my-custom-event', '[$event]‘) onMyCustomEvent(event) {...}

を使用して、たとえば、親に子でDOMのイベントを発行し、それらに耳を傾けることができますが

+0

ok、私はそれをチェックし、あなたに知らせるでしょう:) –

+0

ありがとう。私は使用することを決めたソリューションを追加しました。あなたはすばやく見て、これが正しいアプローチであるかどうか教えてください。 Angularはクライアントベースであり、ブラウザの同じタブ内で魅力的に機能すると仮定しているため、そうだと思います。どう思いますか? –

+0

私はアプローチが良いと思う。私はあなたのアプリケーションの文脈において、「複数のダイアログ」が何を意味するのかを訴えません。ダイアログごとに異なるダイアログサービスを用意することもできますが、それはアプリケーションの設計方法と正確に何を達成しようとしているかによって異なります。 –

関連する問題