angular ng-zorro 可编辑表格结合响应式表单,增加,删除,编辑一行

angular和ng-zorro 可编辑表格,响应式表单,增加,删除,编辑一行,并附有校验功能

效果图:

table-edit-row.component.html

<form nz-form [formGroup]="validateForm">
    <button nz-button nzType="dashed" class="add-button" (click)="addRow()">
        <i nz-icon nzType="plus"></i>
        Add field
    </button>&nbsp;&nbsp;
    <button nz-button (click)="submitData()" nzType="primary">提交</button>&nbsp;&nbsp;
    <br />
    <br />
    <nz-table [nzShowPagination]="false" nzSize="middle" #editRowTable nzBordered [nzData]="listOfData">
        <thead>
            <tr>
                <th>Name</th>
                <th>Mobile</th>
                <th>Address</th>
                <th nzWidth="200px">Action</th>
            </tr>
        </thead>
        <tbody>
            <ng-container formArrayName="aliases">
                <tr [formGroupName]="i" *ngFor="let data of aliases.controls;let i=index" class="editable-row">
                    <ng-container *ngIf="editId != data.value.id; else editTemplate">
                        <td>
                            {{data.value.name}}
                        </td>
                        <td>
                            {{data.value.mobile}}
                        </td>
                        <td>
                            {{data.value.address}}
                        </td>
                        <td>
                            <a (click)="deleteRow(i)">delete</a>&nbsp;&nbsp;
                            <a (click)="startEdit(data.value)">edit</a>&nbsp;&nbsp;
                        </td>
 
                    </ng-container>
                    <ng-template #editTemplate>
                        <ng-container>
                            <td>
                                <nz-form-item>
                                    <nz-form-control nzSpan="1-24" nzErrorTip="请输入姓名">
                                        <input type="text" nz-input formControlName="name" maxlength="4" />
                                    </nz-form-control>
                                </nz-form-item>
                            </td>
                            <td>
                                <nz-form-item>
                                    <nz-form-control nzSpan="1-24" [nzErrorTip]="errorTpl">
                                        <input type="text" nz-input formControlName="mobile" />
                                        <ng-template #errorTpl let-control>
                                            <ng-container *ngIf="control.hasError('required')">请输入电话</ng-container>
                                            <ng-container *ngIf="control.hasError('confirm')">
                                                请输入正确格式的电话号码
                                            </ng-container>
                                        </ng-template>
                                    </nz-form-control>
                                </nz-form-item>
                            </td>
                            <td>
                                <nz-form-item>
                                    <nz-form-control nzSpan="1-24" nzErrorTip="请输入地址">
                                        <input type="text" nz-input formControlName="address" />
                                    </nz-form-control>
                                </nz-form-item>
                            </td>
                            <td>
                                <a (click)="deleteRow(i)">delete</a>&nbsp;&nbsp;
                                <a nzType="link" (click)="saveRow()">save</a>&nbsp;&nbsp;
                                <!-- <a (click)="stopEdit(data.value)">cancel</a>&nbsp;&nbsp; -->
                            </td>
                        </ng-container>
                    </ng-template>
                </tr>
            </ng-container>
        </tbody>
    </nz-table>
    <nz-pagination [nzPageSize]="10" [(nzPageIndex)]="current" [nzTotal]="listOfData.length"></nz-pagination>
 
 
</form>

table-edit-row.component.ts

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormControl, FormGroup, FormArray, Validators } from '@angular/forms';
import { NzMessageService } from 'ng-zorro-antd/message';
 
 
interface ItemData {
  id: string;
  name: string;
  mobile: string;
  address: string;
}
 
@Component({
  selector: 'app-table-edit-row',
  templateUrl: './table-edit-row.component.html',
  styleUrls: ['./table-edit-row.component.css']
})
 
export class TableEditRowComponent implements OnInit {
  validateForm!: FormGroup;
 
  current:number = 1;
 
  i = 0;
  rowData: object = {};
  editId: string | null = null;
  listOfData: ItemData[] = [{
    id: '001',
    name: '小明1',
    mobile: '13120257131',
    address: '上海',
  }, {
    id: '002',
    name: '小明2',
    mobile: '13120257132',
    address: '北京',
  },{
    id: '003',
    name: '小明3',
    mobile: '13120257131',
    address: '广州',
  }];
 
  startEdit(rowData: any): void {
    for (const i in this.validateForm.controls) {
      if (this.validateForm.controls.hasOwnProperty(i)) {
        this.validateForm.controls[i].markAsDirty();
        this.validateForm.controls[i].updateValueAndValidity();
      }
    }
    if (!this.validateForm.valid) {
      this.message.create('error', '只能同时编辑一行')
    } else {
      this.rowData = rowData;
      this.editId = rowData.id;
    }
 
  }
 
  stopEdit(row: any): void {
    //取消 有bug 暂时先不显示
    for (let index = 0; index < this.validateForm.value.aliases.length; index++) {
      const element = this.validateForm.value.aliases[index];
      if (element.id == row.id) {
        this.validateForm.value.aliases[index] = this.rowData;
        console.log('this.validateForm.value.aliases', this.validateForm.value.aliases)
      }
    }
    let tempList = this.validateForm.value.aliases;
    this.validateForm.patchValue({
      aliases: tempList
    })
    this.editId = null;
  }
 
  addRow(): void {
    let allowAdd = false;
    for (let index = 0; index < this.validateForm.value.aliases.length; index++) {
      const element = this.validateForm.value.aliases[index];
      if (element.name && element.mobile && element.address) {
        allowAdd = true;
      } else {
        allowAdd = false;
      }
    }
    if (allowAdd) {
      // if (this.validateForm.valid) {
      let editId = JSON.stringify(Date.now());
      this.aliases.push(this.fb.group({
        id: editId,
        name: ['', [Validators.required]],
        mobile: ['', [Validators.required, this.confirmationValidator]],
        address: ['', [Validators.required]],
      }))
      this.editId = editId;
    } else {
      this.message.create('error', '只能新增一行')
    }
  }
  saveRow() {
    // this.editId = null;
    if (this.validateForm.valid) {
      this.editId = null;
      console.log('value', this.validateForm.value.aliases)
    } else {
      this.message.create('error', '请完善此行信息')
    }
  }
  submitData() {
    for (const i in this.validateForm.controls) {
      if (this.validateForm.controls.hasOwnProperty(i)) {
        this.validateForm.controls[i].markAsDirty();
        this.validateForm.controls[i].updateValueAndValidity();
      }
    }
    if (!this.validateForm.valid) {
      this.message.create('error', '请补全信息')
    }
    if (this.validateForm.valid) {
      console.log('submit:', this.validateForm.value.aliases)
    }
  }
 
  deleteRow(index: any): void {
    // console.log(index);
    this.removeFormArrayItem(index);
    console.log('this.validateForm.value.aliases', this.validateForm.value.aliases)
    // this.listOfData = this.listOfData.filter(d => d.id !== id);
  }
  get aliases() {
    return this.validateForm.get('aliases') as FormArray;
  }
  //删除表单组
  removeFormArrayItem(index: any) {
    this.aliases.removeAt(index);
  }
  // 生成唯一值
  getUID() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
      const r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
      return v.toString(16);
    });
  }
  confirmationValidator = (control: FormControl): { [s: string]: boolean } => {
    if (!control.value) {
      return { required: true };
    } else if (!(/^1[3456789]\d{9}$/.test(control.value))) {
      return { confirm: true, error: true };
    }
    return {};
  };
  constructor(
    private fb: FormBuilder,
    private message: NzMessageService
  ) {
 
  }
  ngOnInit(): void {
    this.validateForm = this.fb.group({
      aliases: this.fb.array([])
    })
    for (let index = 0; index < this.listOfData.length; index++) {
      const element = this.listOfData[index];
      this.aliases.push(this.fb.group({
        id: element.id,
        name: [element.name, [Validators.required]],
        mobile: [element.mobile, [Validators.required, this.confirmationValidator]],
        address: [element.address, [Validators.required]],
      }))
    }
    // console.log(this.validateForm)
    console.log(this.aliases.controls)
  }
}
 
 

 

posted @ 2021-08-19 14:46  汪洋是大大的海  阅读(1497)  评论(6编辑  收藏  举报