web-dev-qa-db-ja.com

Angular 4と互換性のあるモーダルポップアップを作成する方法

ラジオボタンが選択されたときに私の特定のAngular 4コンポーネントをロードするポップアップウィンドウを作成できるようにしたいと思います。

これに対する答えにリストされているメソッド question は、Angular 2とのみ互換性があるようです。

どこから始めればよいかわからないので、助けていただければ幸いです!

19
Luca Guarro

Angular Material Dialogue を確認します。これは Plunker です

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<DialogResultExampleDialog>) {}
}
13
Madhu Ranjan

受け入れられた答えは、ハエを叩くために大きな依存関係を追加します。モーダル(およびモードレス)ダイアログは、主に1つまたは2つのCSSクラスの結果です。この「名前変更...」の例を試してください。

1)子がまったくモーダルではなく、* ngIfが添付されたインラインフォームのように、親と子モーダルを記述します。

<my-modal>子を使用する親HTML:

<div>
    A div for {{name}}.
    <button type="button" (click)="showModal()">Rename</button>
    <my-modal *ngIf="showIt" [oldname]="name" (close)="closeModal($event)"></my-modal>
</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;
    }

}

子になるモーダルコンポーネント。 @Componentデコレータとインポートは再び省略されました。

export class MyModalComponent {
    @Input() oldname = "";
    @Output() close = new EventEmitter<string>();
    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;" />
    <button type="button" (click)="ok()">OK</button>
    <button type="button" (click)="cancel()">Cancel</button>
</div>

2)子用の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;
}

3)子HTMLでmodalおよびoverlayを使用します。

<div class="modal">
    Rename {{oldname}}
    <input type="text" (change)="newname = $event.target.value;" />
    <button type="button" (click)="ok()">OK</button>
    <button type="button" (click)="cancel()">Cancel</button>
</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つのこと:

<my-modal>に* ngIfが存在する場合、this.renameModal.show(..);は機能しません。最初に関数を公開するために存在しないためです。 * ngIfはコンポーネント全体、show()関数、およびすべてを削除するため、何らかの理由でこれが必要な場合は、代わりに[hidden]を使用してください。

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

17
Ron Newcomb