Angular Mat-table DataSource 值在更新状态时发生了变化

Angular Mat-table DataSource value changed while updating the status

table -> 操作 -> 无效

当我们更改行状态值时,mat-table 数据源值也会更新。

我们的要求是更新到数据库后改变状态值,但是现在mat-table立即改变状态值。

我们如何停止 mat-table 数据源更新?

我已经给出了例子。 请查看 stackblitz

HTML

<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
  <!--- Note that these columns can be defined in any order.
        The actual rendered columns are set as a property on the row definition" -->

  <!-- Position Column -->
  <ng-container matColumnDef="position">
    <th mat-header-cell *matHeaderCellDef>No.</th>
    <td mat-cell *matCellDef="let element">{{element.position}}</td>
  </ng-container>

  <!-- Name Column -->
  <ng-container matColumnDef="name">
    <th mat-header-cell *matHeaderCellDef>Name</th>
    <td mat-cell *matCellDef="let element">{{element.name}}</td>
  </ng-container>

  <!-- Weight Column -->
  <ng-container matColumnDef="weight">
    <th mat-header-cell *matHeaderCellDef>Weight</th>
    <td mat-cell *matCellDef="let element">{{element.weight}}</td>
  </ng-container>

  <!-- Symbol Column -->
  <ng-container matColumnDef="symbol">
    <th mat-header-cell *matHeaderCellDef>Symbol</th>
    <td mat-cell *matCellDef="let element">{{element.symbol}}</td>
  </ng-container>
  <ng-container matColumnDef="status">
    <th mat-header-cell *matHeaderCellDef>status</th>
    <td mat-cell *matCellDef="let element">{{element.status}}</td>
  </ng-container>
  <ng-container matColumnDef="actions">
    <th mat-header-cell *matHeaderCellDef>Actions</th>
    <td mat-cell *matCellDef="let element">
      <button
        mat-button
        [matMenuTriggerFor]="menu"
        class="nav-link dropdown-toggle mobile-data"
      >
        Acción
      </button>
      <mat-menu #menu="matMenu">
        <button
          mat-menu-item
          class="dropdown-item"
          (click)="updateStatus('inActive',element)"
        >
          <span>InActive</span>
        </button>
      </mat-menu>
    </td>
  </ng-container>
  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

ts

import { Component } from '@angular/core';

/**
 * @title Basic use of `<table mat-table>`
 */
@Component({
  selector: 'table-basic-example',
  styleUrls: ['table-basic-example.css'],
  templateUrl: 'table-basic-example.html',
})
export class TableBasicExample {
  displayedColumns = [
    'position',
    'name',
    'weight',
    'symbol',
    'status',
    'actions',
  ];
  dataSource = ELEMENT_DATA;
  updateStatus(status, item) {
    console.log('before set status', this.dataSource);
    item.status = status;
    console.log('After set status', this.dataSource);
  }
}

export interface PeriodicElement {
  name: string;
  position: number;
  weight: number;
  symbol: string;
  status: string;
}

const ELEMENT_DATA: PeriodicElement[] = [
  {
    position: 1,
    name: 'Hydrogen',
    weight: 1.0079,
    symbol: 'H',
    status: 'Active',
  },
  {
    position: 2,
    name: 'Helium',
    weight: 4.0026,
    symbol: 'He',
    status: 'Active',
  },
  {
    position: 3,
    name: 'Lithium',
    weight: 6.941,
    symbol: 'Li',
    status: 'Active',
  },
];

stackblitz 演示:https://stackblitz.com/edit/angular-keucik?file=app/table-basic-example.ts

问题在于,当您修改元素时,您正在修改 table 的源代码。 (数据源)

如果不修改 table,您将无法编辑项目的值。但是你可以创建一个辅助数组,来保持你的新状态。

Example

TS

import { Component } from '@angular/core';
import { MatTableDataSource } from '@angular/material';

/**
 * @title Basic use of `<table mat-table>`
 */
@Component({
  selector: 'table-basic-example',
  styleUrls: ['table-basic-example.css'],
  templateUrl: 'table-basic-example.html',
})
export class TableBasicExample {
  displayedColumns = [
    'position',
    'name',
    'weight',
    'symbol',
    'status',
    'actions',
  ];
  dataSource = ELEMENT_DATA;
  dataSourceAux = JSON.parse(JSON.stringify(ELEMENT_DATA));

  updateStatus(status, item) {
    const idx = this.dataSourceAux.findIndex((x) => x.name === item.name);
    this.dataSourceAux[idx].status = status;
    /**
     * or const itemAux = this.dataSourceAux.find((x) => x.name === item.name)
     * itemAux.status = status;
     *
     * Now you have two list, one with the real table values, and another with the copy of them
     * And what you should do, is change the value of the auxiliar list, not the real.
     * when you want to update the table, just do
     * this.dataSource = JSON.parse(JSON.stringify(this.dataSourceAux))
     */
  }
}

export interface PeriodicElement {
  name: string;
  position: number;
  weight: number;
  symbol: string;
  status: string;
}

/**  Copyright 2018 Google Inc. All Rights Reserved.
    Use of this source code is governed by an MIT-style license that
    can be found in the LICENSE file at http://angular.io/license */

const ELEMENT_DATA: PeriodicElement[] = [
  {
    position: 1,
    name: 'Hydrogen',
    weight: 1.0079,
    symbol: 'H',
    status: 'Active',
  },
  {
    position: 2,
    name: 'Helium',
    weight: 4.0026,
    symbol: 'He',
    status: 'Active',
  },
  {
    position: 3,
    name: 'Lithium',
    weight: 6.941,
    symbol: 'Li',
    status: 'Active',
  },
];

代码,它可以更好更安全。但这只是一个例子。