简体   繁体   English

Angular 材质 MatTable 似乎重新加载先前渲染的行上的数据?

[英]Angular Material MatTable appears to reload data on previously rendered rows?

I am using the MatTable in which the first row is pre-populated with a MatAutocomplete input control that is bound to a dynamic data call.我正在使用 MatTable,其中第一行预先填充了绑定到动态数据调用的 MatAutocomplete 输入控件。 Everything works as expected there.那里的一切都按预期工作。

I have an "Add Row" button that calls a method to update the table with a new row.我有一个“添加行”按钮,它调用一种方法来用新行更新表。 The issue I'm trying to resolve or better understand is that it appears that when the new row is added, all the previous rows get reloaded even though their data has not changed.我试图解决或更好地理解的问题是,当添加新行时,所有先前的行都会重新加载,即使它们的数据没有改变。

I'm using onPush changedetection.我正在使用 onPush 更改检测。 Anyone know if its possible to optimize the matTable to not rerender previously rendered rows?任何人都知道是否可以优化 matTable 以不重新渲染先前渲染的行?

addRow(event: any) {
    this.clearSort();
    this.clearFilter(undefined);
    const currentData = cloneDeep(this.formArrayValues);
    currentData.push(this.emptyRowFromColumnDef); // Append new row to END of table
    this.updateTableData(currentData);
    if (this.paginationEnable && this.paginator) {
      // move table paging to last page to see newly added row. setTimeout helps avoid sync delay
      timer().subscribe(() => this.paginator.lastPage());
    }
    timer(1).subscribe(() => this.changeDetectorRef.markForCheck());
    event.preventDefault();
  }


get emptyRowFromColumnDef(): any {
  const item = {};
  const columns = get(this.tableConfig, `columns`, []);
  const columnTypes = get(this.tableConfig, `columnTypes`, {});
  if (columns.length) {
    for (let i = 0; i < columns.length; i++) {
      if (columns[i] === this.SELECTION_COLUMN_NAME) {
        item[columns[i]] = true;
      } else {
        // Todo - Set this to the correct default type. Should be able to use tableConfig
        item[columns[i]] = this.defaultEmptyValueByType(columns[i], columnTypes[columns[i]]);
      }
    }
  }

  return item;
}

get formArrayValues(): any[] {
  return this.formArray.getRawValue();
}

get formArray(): FormArray {
  return <FormArray>this.formControl;
}


updateTableData(datasource: any) {
  this.resetFilterIfActive();
  const useData = this.defaultEmptyColumnData(this._limitDataByMode(datasource));
  this.data = useData;
  if (this.paginationEnable) {
    this.paginatorLength = useData.length || 0;
  }
  this.syncDatasourceToFormControl();
  this.renderRows();
}


syncDatasourceToFormControl() {
  if (!['builder'].includes(this.jsf.mode)) {

    if (this.formArray && isFunction(this.formArray.clear)) {
      this.formArray.clear();
    }

    let data = this.data || [];
    this.formArrayUpdateAll();

    if (this.options.rowSelection) {
      data = this.defaultUndefinedSelection(data);
    }

    if (this.formArray) {
      this.bindDataToForm(data);
      this.renderRows();
      this.testLogicSyncChanges();
    }
  }
}


formArrayUpdateAll() {
    const dataTotal = (this.data || []).length;
    const $refNode = this._getRefNode();
    if ($refNode) {
      $refNode.options.tableItem = true;
      for (let i = 0; i < dataTotal; i++) {
        const index = i + 1;
        const $ref = {
          layoutNode: $refNode,
          layoutIndex: this.layoutIndex.concat(index),
          dataIndex: this.dataIndex.concat(index)
        };
        this.jsf.addItem($ref);
      }
    }
  }

I'm assuming by 'reloaded' you mean 'rerendered'.我假设“重新加载”是指“重新渲染”。 You might be able to use trackBy.您也许可以使用 trackBy。 From material angular docs:来自材料 angular 文档:

To improve performance, a trackBy function can be provided to the table similar to Angular's ngFor trackBy.为了提高性能,可以将 trackBy function 提供给表,类似于 Angular 的 ngFor trackBy。 This informs the table how to uniquely identify rows to track how the data changes with each update.这会通知表如何唯一标识行以跟踪数据如何随每次更新而变化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM