<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类不会阻止与下面页面的交互。 (因此,它在技术上创建了一个非模态对话框。)因此,我们在modal
下方放置一个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类,您就可以使任何组件成为模态窗口。实际上,您可以通过使用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"
或类似方法解决。
<my-modal (close)="closeModal($event)">
,这是子组件触发的 close
事件被捕获并传递到父级控制器的 closeModal
函数的地方。 - Ron NewcombmodalObject.popup()
,其中这个modalObject
可以在运行时初始化。因此,在应用程序模板中不应该留下这个组件的任何痕迹。 - windmaomao查看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>) {}
}