Angular Material的弹窗组件dialog取消mat-dialog-actions自动关闭
场景
在使用Angular Material(https://material.angular.io/)的dialog组件时遇到了一个问题
按照官网上的步骤发现不管点击取消还是确认,都会在关闭dialog弹窗后才能获取到数据,
这就导致了当我要在dialog中添加表单并进行验证时,不管验证是否成功都会关闭弹窗
思路一
虽然考虑过用disabled来解决问题,但总觉得这样的解决方案不符合用户交互规范,应该在点击确认时,先根据校验规则提示用户的不规范填写,而不是直接禁用
思路二
想到可不可以不用在html中使用mat-dialog-actions属性,而是通过js / ts 在提交并验证成功后再手动调用关闭弹窗并传值
根据这个思路最后找到了解决方案
关键代码
<div mat-dialog-actions>
<button mat-button (click)="onNoClick()">关闭</button>
<button mat-button cdkFocusInitial (click)="submit($event)">增加</button>
</div>
submit(e){
if(!this.netAddForm.invalid){
this.dialogRef.close(this.newNet);//当表单验证成功后才调用close,并将信息传递给dialog组件
}
}
最后贴出完整代码
<p>新增网络</p>
<form [formGroup]="netAddForm">
<div mat-dialog-content class="input-form">
<mat-form-field appearance="legacy" class="input-full-width">
<mat-label>网络名称</mat-label>
<input matInput [(ngModel)]="newNet.name" [formControl]="rules.name"/>
<mat-error *ngIf="rules.name.invalid">{{getErrorMessage()}}</mat-error>
</mat-form-field>
<br/>
<mat-form-field appearance="legacy" class="input-full-width">
<mat-label>网络ID</mat-label>
<input matInput [(ngModel)]="newNet.netid" [formControl]="rules.netid"/>
<mat-error *ngIf="rules.netid.invalid">{{getNetIDErrorMessage()}}</mat-error>
</mat-form-field>
<br/>
</div>
<div mat-dialog-actions>
<button mat-button (click)="onNoClick()">关闭</button>
<button mat-button cdkFocusInitial (click)="submit($event)">增加</button>
</div>
</form>
import {Component, Inject} from '@angular/core';
import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
import * as _ from 'lodash';
import {FormBuilder, FormControl, FormGroup, Validators} from '@angular/forms';
import { network } from '../function.models';
export interface DialogData {
newNet:{
name: string;
netid:string;
}
}
@Component({
selector: 'network-dialog',
templateUrl: './network-dialog.component.html',
styleUrls: ['./network-dialog.component.css'],
})
export class NetWorkDialog {
newNet: network = {
netid: null,
name: null,
};
netAddForm:FormGroup;
rules={
name:new FormControl('', [Validators.required, Validators.pattern(/^[一-龥A-Za-z0-9_^%;=?@$"]+$/)]),
netid:new FormControl('', [Validators.required, Validators.pattern(/^[0-9]+$/) ]),
}
constructor(
public dialogRef: MatDialogRef<NetWorkDialog>,
@Inject(MAT_DIALOG_DATA) public data: DialogData,
fb:FormBuilder,
public dialog: MatDialog) {
this.netAddForm = fb.group({
name:this.rules.name,
netid:this.rules.netid,
})
}
onNoClick(): void {
this.dialogRef.close();
}
getErrorMessage() {
if (this.rules.name.hasError('required')) {
return '必须输入值';
}
if(this.rules.name.hasError('pattern')){
return '请输入合法字符串'
}
}
getNetIDErrorMessage(){
if (this.rules.netid.hasError('required')) {
return '必须输入值';
}
if(this.rules.netid.hasError('pattern')){
return '必须输入数字'
}
}
submit(e){
if(!this.netAddForm.invalid){
this.dialogRef.close(this.newNet);
}
}
}
调用dialog组件的父组件中
<button mat-raised-button (click)="openDialog()" color="primary">新增网络</button>
import { NetWorkDialog } from '../dialogs/network-dialog.component';
import { network } from '../function.models';
export class NetworkComponent implements OnInit {
newNet: network = {
netid: null,
name: null,
};
openDialog(): void {
const dialogRef = this.dialog.open(NetWorkDialog, {
width: '470px',
data: {
newNet:{
name: this.newNet?.name,
netid:this.newNet?.netid,
}
}
});
dialogRef.afterClosed().subscribe(result => {
console.log('The dialog was closed',result);
this.newNet = result;
});
}
表单验证及弹窗自动关闭问题分别有参考链接
https://www.thinbug.com/q/51686251
https://pdf-lib.org/Home/Details/12304