本文已参与「新人创作礼」活动,一起开启掘金创作之路。 思路:通过一个具有多项设置的数组传值给弹窗,使弹窗进行不同的组件组合显示,且创建一个Form表单用于弹窗传值调用API。
弹窗代码
<div mat-dialog-content class="p-24 pb-0 m-0" fusePerfectScrollbar>
<form [formGroup]="formData">
<div *ngFor="let form of formColumn; let i=index" fxLayout="row" fxLayoutAlign="start start">
<mat-form-field appearance="outline" fxFlex *ngIf="form.type !== 'imgFile'; else uploadFile"
[ngSwitch]="form.type" [class]="form.type==='time' ? 'dateTime_field' : ''">
<mat-label>{{ form.label }}</mat-label>
<input *ngSwitchDefault [type]="form.type ? form.type : ''" [name]="form.value" [formControlName]="form.value"
matInput [required]="form.required">
<div *ngSwitchCase="'exportTemplate'">
{{form.label}}
</div>
<div *ngSwitchCase="'time'" class="dateTime_box">
<input matInput [matDatepicker]="timePicker" [required]="form.required" [name]="form.value"
[formControlName]="form.value">
<mat-datepicker-toggle matSuffix [for]="timePicker"></mat-datepicker-toggle>
<mat-datepicker #timePicker></mat-datepicker>
</div>
<mat-select *ngSwitchCase="'select'" [formControlName]="form.value" [required]="form.required">
<mat-option *ngFor="let opt of form.selectArr" [value]="opt.value">
{{ opt.label }}
</mat-option>
</mat-select>
<mat-select *ngSwitchCase="'select2'" [formControlName]="form.value" [required]="form.required">
<mat-option *ngFor="let opt of form.selectArr" [value]="opt">
{{ opt.label }}
</mat-option>
</mat-select>
<textarea *ngSwitchCase="'textarea'" [name]="form.label" [formControlName]="form.value" matInput type="text"
max-rows="4" [required]="form.required">
</textarea>
</mat-form-field>
<ng-template #uploadFile>
<mat-label class="file_label">{{ form.label }}</mat-label>
<!-- checkbox多选组 -->
<mat-selection-list *ngIf="form.label === '渠道选择'; else Img" [formControlName]="form.value">
<mat-list-option checkboxPosition="before" *ngFor="let lt of form.checkArr" [value]="lt.value">
{{ lt.label }}
</mat-list-option>
</mat-selection-list>
<!-- 图片上传组件 -->
<ng-template #Img>
<upload-img [options]="formInit[form.value]" [detailType]="detailType" [multiple]="multiple"
(receiveImg)="receiveImage($event)">
</upload-img>
</ng-template>
</ng-template>
</div>
</form>
</div>
从上往下分析一下代码核心部分的的逻辑:
- [formGroup]="formData":Form表单名称为formData
- *ngFor="let form of formColumn; let i=index":formColumn为数组,用于规定组件的组合显示,ngfor使得可以根据数组的数量显示指定数量的组件。
- [ngSwitch]="form.type":type规定类型,是否是图片上传、输入框、时间选择器等。
- [formControlName]="form.value":formControl类型,用于弹窗传值,以formColumn数组内的value值命名
- [required]="form.required":是否必填
继续往下同理,其实和ng2-chart很像,通过一个数组对图表(弹窗)进行详细的设置。
弹窗的调用
/**
* 新增供应商
*/
addSupplier(): void {
const dialogRef = this.matDialog.open(DialogFormComponent, {
panelClass: 'dialog-form', //调用的组件
data: {
action: 'add', //规定按钮的类型是添加、编辑还是保存
title: '新增供应商', //弹窗的标题
formColumn: this.addSupplierForm, //规定组件的数组
}
});
dialogRef.afterClosed().subscribe( //弹窗关闭后传值
async (res) => {
console.log(res);
if (res && res.form) {
const result = await this.confSvc.sendPutCatch('procurement/suppliers/id', res.form);
if (result['data'] && result['data'].length > 0) {
this.confSvc.handleTip(result['msg']);
}
else {
this.confSvc.handleTip(result['msg']);
}
}
}
);
}
规定组件的数组格式
// 新增供应商弹窗Form
addSupplierForm = [
{
label: '供应商编号', //组件的label名称
value: 'suppliers_code', //value值用于弹窗关闭后传值,不能重复
type: 'input', //input代表为input框
required: true //是否必填
},
{
label: '供应商类型',
value: 'source_id',
type: 'select', //select代表为下拉框
selectArr: [ //下拉框的选项,当然这里也可以调用API的数组,直接selectArr:数组名即可
{
label: '零星采购',
value: 1
},
{
label: '批量外采',
value: 12
}
],
required: true
},
{
label: '说明',
value: 'suppliers_description',
type: 'input',
required: false
},
];
弹窗组件的核心代码
创建表单:
/**
* 创建表单
* @returns {FormGroup}
*/
createNewForm(): FormGroup {
const formObj = {};
this.formColumn.forEach(item => {
formObj[item.value] = [this.formInit[item.value]];
});
return this._formBuilder.group(formObj);
}
设置弹窗的默认值
这时候产品经理告诉我,另一个地方输入框要有默认值,我试过了在组件数组中加入默认值deaults,在input框加入[value]="deaults",然而只是静态显示,并不会有数据绑定。
于是我决定从formControlName下手。
这是一个填写几行数量的弹窗,规则组件的数组格式如下:
this.skuData.forEach((value => {
this.skuForm.push({
label: value['products_sku'] + ' 入库数量',
value: value['products_sku'],
type: 'input',
defaults: value['order_qty'] - value['back_qty'],
required: true
});
}));
其中defaults为计算后想要默认显示的值。
改写弹窗的表单处理函数:
/**
* 创建表单
* @returns {FormGroup}
*/
createNewForm(): FormGroup {
const formObj = {};
this.formColumn.forEach(item => {
formObj[item.value] = [this.formInit[item.value]];
});
// 使表单的formControl值等于默认值defaults
this.formColumn.forEach((item, index, value) => {
// 判断defaults值是否为空,如果为空则不设置默认值
if (value[index].defaults !== null && value[index].defaults !== '' && value[index].defaults !== undefined) {
formObj[item.value] = [value[index].defaults];
}
});
return this._formBuilder.group(formObj);
}
完成!