Angular ng-zorro-antd 使用nz-table,更改数据不渲染的问题

最近在工作中使用angular,组件库使用ng-zorro-antd,边学边用。在写表格组件的时候发现,点击新增、删除就,数据改变,表格却没有更新。

代码如下:

<a (click)="addRow(item)">新增一列</a>
<nz-table
  #basicTable
  class="form-table"
  [nzBordered]="true"
  [nzData]="fields"
  [nzShowPagination]="false">
  <thead>
    <tr>
      <th>值的编号</th>
      <th>字段</th>
      <th>操作</th>
    </tr>
  </thead>
  <tbody cdkDropList (cdkDropListDropped)="drop($event, fields)">
    <!-- <tr *ngFor="let data of fields, let i = index" cdkDrag> -->
    <tr *ngFor="let data of basicTable.data, let i = index" cdkDrag>
      <td>值{{ i + 1 }}</td>
      <td>{{ data.fields }}</td>
      <td>
        <a (click)="deleteRow(item, i, index, data.$sortOperation)">删除</a>
      </td>
    </tr>
  </tbody>
</nz-table>

对表格行数据遍历有2种写法,如下:

// 写法1
<tr *ngFor="let data of fields, let i = index" cdkDrag>

// 写法2
<tr *ngFor="let data of basicTable.data, let i = index" cdkDrag>
如果采用写法1

写法是官网示例的写法之一
点击新增时,数据push进去了,但是表格没有新增一条

addRow(item) {
    item.fields.push({
        ...cloneDeep(fieldsGroup),
        add_id: addId,
    });
}

但使用如下写法,点击新增时,数据push进去了,但是表格没有成功显示新增

addRow(item) {
    item.fields = [
        ...item.groupByFields,
        {
          ...cloneDeep(fieldsGroup),
          add_id: addId,
        },
    ];
}

同理删除的时候也是如此:
点击删除按钮的时候,使用splice删除一行,该数据已经删除,但表格页面数据没有消失

  deleteRow(item, index, tableIndex, sortOperation) {
    item.fields.splice(index, 1);
  }

但是如果使用filter,将过滤后的结果重新赋值,表格成功删除一条

  deleteRow(item, index, tableIndex, sortOperation) {
    item.fields = item.fields.filter(item => item.$sortOperation !== sortOperation);
  }

另外,如果只用表格拖拽功能时,写法1也不能成功拖拽表格顺序。

如果采用写法2

如果采用写法2,上面的2中写法都可以实现效果。

分析

查找ng-zorro-antd源码,发现其中是这么写的:当nzData发生变化的时候重新渲染。

  ngOnChanges(changes: SimpleChanges): void {
    if (nzData) {
      this.nzData = this.nzData || [];
      this.nzTableDataService.updateListOfData(this.nzData);
    }
  }

查找发现

当Angular检查组件的输入属性以进行更改时,它(基本上)===使用脏检查。对于数组,这意味着对数组引用(仅)进行脏检查。由于引用没有改变,ngOnChanges()因此不会被调用。
OnChanges只对输入的基本数据类型起作用,而引用数据类型不会触发OnChanges方法。

当使用写法1的时候,由于是引用数据类型,对表格行数据进行操作,不会触发OnChanges方法,是不会触发表格组件的重新渲染的,但是重新赋值改变了nzData的引用,会触发OnChanges方法。

ng-zorro-antd官网使用写法1是因为其数据结构简单,这个问题就不会出现。在自己的工作中,数据层级多,问题出现。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容