公认的答案是,打一只苍蝇需要添加一个很大的依赖关系。 模态(和无模态)对话框在很大程度上是一两个 CSS 类的结果。试试这个重命名......的例子:
使用<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>
.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;
}
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 类,你就可以将任何组件变成模态。 事实上,只需使用 ngClass
或 [class.modal]="showAsModalBoolean"
来改变 CSS 类的存在,就能在运行时显示内嵌组件或模态组件。
您可以改变这种方式,让子代控制显示/隐藏逻辑。将 *ngIf、showIt 和 show() 函数移到子代中。 在父代中添加@ViewChild(MyModalComponent) renameModal: MyModalComponent;
,然后父代可以强制调用this.renameModal.show(this.name);
,并根据需要重新连接初始化和包含的 div。
如上所示,子模态可以将信息返回给父模态的函数,或者子模态的 show()
方法可以接受回调或返回 Promise。
有两点需要注意:
如果在<my-modal>
上有一个 ngIf ,this.renameModal.show(...);
将不起作用,因为它一开始就不存在以暴露函数。ngIf 会移除整个组件、show() 函数和所有内容,因此如果出于某种原因需要这样做,请使用 [hidden]
。
模态上的模态会有 z-index 问题,因为它们都共享相同的 z-index。这可以通过 [style.z-index]="calculatedValue"
或类似方法解决。
查看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>) {}
}