美文网首页
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