美文网首页
Angular 动态添加表单和排序

Angular 动态添加表单和排序

作者: 河码匠 | 来源:发表于2018-12-11 16:25 被阅读0次

简介

用户需要批量添加数据且数据内容和多少不确定时,需要动态控制表单数量。

效果如下:


效果.gif

使用插件

  1. 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() {

  }
}
  1. 需要注意51~60行,其中 id 是动态表单必须字段。为了让 input 中的 name 不重复,我定义input的name 是 name+id 组的字符串,其他字段是 input 的双向绑定定义的值。这样才可以在controlArray中获取用户填写后的结果。
  2. 在upField和downField 函数中对 id 的操作是为了上传的时候看着比较舒服,不改也没什么影响。

相关文章

网友评论

      本文标题:Angular 动态添加表单和排序

      本文链接:https://www.haomeiwen.com/subject/kixdhqtx.html