简介
用户需要批量添加数据且数据内容和多少不确定时,需要动态控制表单数量。
效果如下:
效果.gif
使用插件
- NG-ZORRO
代码
html 文件
<span *ngFor="let control of controlArray;let i = index">
<div nz-row [nzGutter]="6">
<div nz-col [nzSpan]="5">
<nz-form-item>
<nz-form-control>
<input name="dir{{control.id}}" [(ngModel)]="control.dir" nz-input placeholder="{{'Directory. E.g: /images/' | translate}}">
</nz-form-control>
</nz-form-item>
</div>
<div nz-col [nzSpan]="3">
<nz-form-item>
<nz-form-control>
<nz-select class="remove_internal_padding" [(ngModel)]="control.operation" name="operation{{control.id}}">
<nz-option nzValue="cache" nzLabel="{{ 'CDN cache_rule_cache' | translate }}"></nz-option>
<nz-option nzValue="cache_index_page" nzLabel="{{ 'CDN cache_rule_cache_index_page' | translate }}"></nz-option>
<nz-option nzValue="no_cache" nzLabel="{{ 'CDN cache_rule_no_cache' | translate }}"></nz-option>
</nz-select>
</nz-form-control>
</nz-form-item>
</div>
<div nz-col [nzSpan]="2" style="padding-left:0px;padding-right:0px;">
<nz-form-item>
<nz-form-control>
<input name="duration{{control.id}}" [(ngModel)]="control.duration" type="number" nz-input>
</nz-form-control>
</nz-form-item>
</div>
<div nz-col [nzSpan]="2">
<nz-form-item>
<nz-form-control>
<nz-select class="remove_internal_padding" [(ngModel)]="control.time_unit" name="time_unit{{control.id}}" [nzPlaceHolder]="mins">
<nz-option nzValue="mins" nzLabel="{{ 'Minutes' | translate }}"></nz-option>
<nz-option nzValue="hours" nzLabel="{{ 'Hours' | translate }}"></nz-option>
<nz-option nzValue="days" nzLabel="{{ 'Days' | translate }}"></nz-option>
</nz-select>
</nz-form-control>
</nz-form-item>
</div>
<div nz-col [nzSpan]="5">
<nz-form-item>
<nz-form-control>
<input nz-input name="file_type{{control.id}}" [(ngModel)]="control.file_type" placeholder="{{'Add file extensions' | translate}}">
</nz-form-control>
</nz-form-item>
</div>
<div nz-col [nzSpan]="6">
<nz-form-item>
<nz-form-control>
<label nz-checkbox name="check_origin{{control.id}}" [(ngModel)]="control.check_origin">{{ 'Follow
Origin' | translate }}</label>
<button *ngIf="i !== 0" nz-button nzType="default" nzShape="circle" (click)="upField(control, $event)"><i class="fa fa-arrow-up"></i></button>
<button *ngIf="controlArray.length !== i + 1" nz-button nzType="default" nzShape="circle" (click)="downField(control, $event)"><i class="fa fa-arrow-down"></i></button>
<button nz-button nzType="default" nzShape="circle" (click)="removeField(control,$event)"><i class="fa fa-trash"></i></button>
</nz-form-control>
</nz-form-item>
</div>
</div>
</span>
注意:input的 name 不能写死。如果写死的话添加新的 input 的时候无法赋值。
ts 文件
import { Component, OnInit, ViewChild, Output, EventEmitter } from '@angular/core';
import { I18NService } from '@core/i18n/i18n.service';
@Component({
selector: 'app-edit-cdn',
templateUrl: './edit.component.html',
styles: []
})
export class EditCdnComponent implements OnInit {
controlArray: Array<{ id: number }> = [];
isVisible: boolean;
constructor(
public i18n: I18NService,
) {
this.isVisible = false;
}
showModal(): void {
this.isVisible = true;
}
handleCancel(): void {
this.isVisible = false;
}
handleOk(validataForm) {
console.log(this.controlArray);
}
addField(e?: MouseEvent): void {
if (e) {
e.preventDefault();
}
const id = (this.controlArray.length > 0) ? this.controlArray[this.controlArray.length - 1].id + 1 : 0;
const control = {
id,
dir: '',
operation: 'cache',
duration: 1,
time_unit: 'mins',
file_type: '',
check_origin: true
};
this.controlArray.push(control);
}
removeField(i: { id: number }, e: MouseEvent): void {
e.preventDefault();
if (this.controlArray.length > 1) {
const index = this.controlArray.indexOf(i);
this.controlArray.splice(index, 1);
}
}
upField(i: { id: number }, e: MouseEvent): void {
const newControlArray = [];
let pre;
if (this.controlArray.length > 1) {
for (const control of this.controlArray) {
pre = '';
if (control === i) {
pre = newControlArray.pop();
control['id'] = control['id'] - 1;
newControlArray.push(control);
pre['id'] = pre['id'] + 1;
newControlArray.push(pre);
} else {
newControlArray.push(control);
}
}
this.controlArray = newControlArray;
}
}
downField(i: { id: number }, e: MouseEvent): void {
const newControlArray = [];
let next = null;
if (this.controlArray.length > 1) {
for (const control of this.controlArray) {
if (control === i) {
next = control;
} else {
if (next !== null) {
control['id'] = control['id'] - 1;
newControlArray.push(control);
next['id'] = next['id'] + 1;
newControlArray.push(next);
next = null;
} else {
newControlArray.push(control);
}
}
}
}
this.controlArray = newControlArray;
}
ngOnInit() {
}
}
- 需要注意51~60行,其中 id 是动态表单必须字段。为了让 input 中的 name 不重复,我定义input的name 是 name+id 组的字符串,其他字段是 input 的双向绑定定义的值。这样才可以在controlArray中获取用户填写后的结果。
- 在upField和downField 函数中对 id 的操作是为了上传的时候看着比较舒服,不改也没什么影响。
网友评论