Angular 4に対応したモーダル・ポップアップを作成する方法

ラジオボタンが選択されると、あるAngular 4コンポーネントが読み込まれるポップアップウィンドウを作成したいと考えています。

この質問の回答に掲載されている方法は、Angular 2にしか対応していないようです。

どこから手をつけていいのかわからないので、助けていただければ幸いです。

受け入れられた答えは、ハエを叩くために大きな依存性を追加します。 モーダルな(そしてモードレスな)ダイアログは、主にCSSクラス1つ2つの結果です。以下の "rename..."の例を試してみてください。

  1. 親と子のモーダルを、子がモーダルではなく、*ngIfが付いた単なるインラインフォームであるかのように書きます。

親 HTML で `` の子を使用します。

<div>
    A div for {{name}}.
    Rename

</div>

親クラスです。簡潔にするために @Component デコレーターは省略しています。(name プロパティは親クラスに属しており、それを変更するフォームがなくても存在しています)。

export class AppComponent {
    name = "old name";

    showIt = false;
    showModal() {
        this.showIt = true;
    }
    closeModal(newName: string) {
        this.showIt = false;
        if (newName) this.name = newName;
    }

}

子のto-be-modalコンポーネント。また、@Componentデコレーターとインポートは省略されています。

export class MyModalComponent {
    @Input() oldname = "";
    @Output() close = new EventEmitter();
    newname = "";

    ngOnInit() {
        // copy all inputs to avoid polluting them
        this.newname = this.oldname; 
    }

    ok() {
        this.close.emit(this.newname);
    }

    cancel() {
        this.close.emit(null);
    }
}

モーダル化する前の子のHTML。

<div>
    Rename {{oldname}}
    <input type="text" (change)="newname = $event.target.value;" />
    OK
    Cancel
</div>
  1. 子のCSSですが、アプリ全体で再利用できるようにグローバルスタイルシートに配置することができます。これは、modalという単一のクラスで、<div>要素を対象としています。
.modal {
    /* detach from rest of the document */
    position: fixed;

    /* center */
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);

    /* ensure in front of rest of page -- increase as needed */
    z-index: 1001;

    /* visual illusion of being in front -- alter to taste */
    box-shadow: rgba(0,0,0,0.4) 10px 10px 4px;

    /* visual illusion of being a solid object -- alter to taste */
    background-color: lightblue;
    border: 5px solid darkblue;

    /* visual preference of don't crowd the contents -- alter to taste */
    padding: 10px;
}

しかし、modalというCSSクラスは、その下にあるページとのインタラクションを妨げません。(そこで、モーダルの下に overlay を配置して、マウスの動きを吸収して無視するようにしています。overlay<div> 要素にも対応しています。

.overlay {
    /* detach from document */
    position: fixed;

    /* ensure in front of rest of page except modal */
    z-index: 1000;

    /* fill screen to catch mice */
    top: 0;
    left: 0;
    width: 9999px;
    height: 9999px;

    /* dim screen 20% -- alter to taste */
    opacity: 0.2;
    background-color: black;
}
  1. modaloverlay を子の HTML で使用します。
<div class="modal">
    Rename {{oldname}}
    <input type="text" (change)="newname = $event.target.value;" />
    OK
    Cancel
</div>
<div class="overlay"></div>

以上で完成です。 基本的に2つのCSSクラスで、どんなコンポーネントでもモーダルにすることができます。 実際、CSSクラスの存在をngClass[class.modal]="showAsModalBoolean"で変更するだけで、実行時にコンポーネントをインラインで表示したり、モーダルとして表示したりすることができます。

これを変更することで、子プロセスが表示/非表示のロジックを制御することができます。*ngIf、showIt、show()関数を子に移動します。 親では、@ViewChild(MyModalComponent) renameModal: MyModalComponent;を追加して、親は、this.renameModal.show(this.name);を命令的に呼び出し、必要に応じて初期化や包含するdivを再配線することができます。

子モダールは上のように親の関数に情報を返すことができますし、子モダールのshow()メソッドは代わりにコールバックを受け取ったり、好みに応じてPromiseを返したりすることができます。

知っておくべきことが2つあります。

this.renameModal.show(...);は、``に*ngIfが設定されていると動作しません。*ngIfはshow()関数を含むコンポーネント全体を削除するので、何らかの理由でこれが必要な場合は代わりに[hidden]`を使用してください。

モーダル上のモーダルは、すべて同じz-indexを共有しているため、z-indexの問題が発生します。これは、[style.z-index]="calculatedValue"などで解決できます。

解説 (4)
ソリューション

アンギュラー・マテリアル・ダイアログ]1を確認し、ここではプランカーを確認します。

import {Component} from '@angular/core';
import {MdDialog, MdDialogRef} from '@angular/material';

@Component({
  selector: 'dialog-result-example',
  templateUrl: './dialog-result-example.html',
})
export class DialogResultExample {
  selectedOption: string;

  constructor(public dialog: MdDialog) {}

  openDialog() {
    let dialogRef = this.dialog.open(DialogResultExampleDialog);
    dialogRef.afterClosed().subscribe(result => {
      this.selectedOption = result;
    });
  }
}

@Component({
  selector: 'dialog-result-example-dialog',
  templateUrl: './dialog-result-example-dialog.html',
})
export class DialogResultExampleDialog {
  constructor(public dialogRef: MdDialogRef) {}
}
解説 (9)