如何创建与 Angular 4 兼容的模态弹出窗口

我想创建一个弹出窗口,当选择单选按钮时,它将加载我的某个 Angular 4 组件。

这个问题的答案中列出的方法似乎只与 Angular 2 兼容。

我不知道从何入手,希望得到帮助!

公认的答案是,打一只苍蝇需要添加一个很大的依赖关系。 模态(和无模态)对话框在很大程度上是一两个 CSS 类的结果。试试这个重命名......的例子:

  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;
    }

}

即将模态化的子组件。再次省略了 @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 "的单一类,用于"
    "元素。
.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 "也适用于"

"元素。

.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. 在子 HTML 中使用 modaloverlay
<div class="modal">
    Rename {{oldname}}
    <input type="text" (change)="newname = $event.target.value;" />
    OK
    Cancel
</div>
<div class="overlay"></div>

就是这样。 只需 2 个 CSS 类,你就可以将任何组件变成模态。 事实上,只需使用 ngClass[class.modal]="showAsModalBoolean"来改变 CSS 类的存在,就能在运行时显示内嵌组件或模态组件。

您可以改变这种方式,让子代控制显示/隐藏逻辑。将 *ngIf、showIt 和 show() 函数移到子代中。 在父代中添加@ViewChild(MyModalComponent) renameModal: MyModalComponent;,然后父代可以强制调用this.renameModal.show(this.name);,并根据需要重新连接初始化和包含的 div。

如上所示,子模态可以将信息返回给父模态的函数,或者子模态的 show() 方法可以接受回调或返回 Promise。

有两点需要注意:

如果在`上有一个 *ngIf ,this.renameModal.show(...);将不起作用,因为它一开始就不存在以暴露函数。*ngIf 会移除整个组件、show() 函数和所有内容,因此如果出于某种原因需要这样做,请使用[hidden]`。

模态上的模态会有 z-index 问题,因为它们都共享相同的 z-index。这可以通过 [style.z-index]="calculatedValue"或类似方法解决。

评论(4)
解决办法

查看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) {}
}
评论(9)