首页 > 解决方案 > 使用 ngrx 和 trackby 更新 Angular Material Table 数据和列不会刷新 DOM

问题描述

我有那个角材料表:

<table mat-table [dataSource]="data" [trackBy]="trackBy">
  <ng-container
    [matColumnDef]="column.value"
    *ngFor="let column of columns; let i = index"
  >
    <th mat-header-cell *matHeaderCellDef>{{ column.label }}</th>
    <td mat-cell *matCellDef="let element">
      <input
        matInput
        [value]="element[column.value].value"
        type="text"
        (input)="updatedFn($event.target.value)"
      />
    </td>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="columnsToDisplay"></tr>
  <tr mat-row *matRowDef="let row; columns: columnsToDisplay"></tr>
</table>

而这个 ts 文件:

  
  @Component({
    ...
    changeDetection: ChangeDetectionStrategy.OnPush,
  })
  export class StuffComponent implements OnInit, OnChanges {
    @Input() data!: Data[];
    @Input() columns!: Column[];
  
    @Output() updated = new EventEmitter<Updated>();
  
    columnsToDisplay!: string[];
  
    constructor(private cdr: ChangeDetectorRef) {}
  
    trackBy(index: number) {
      return index;
    }
  
    ngOnChanges() {
      this.cdr.markForCheck();
    }
  
    ngOnInit() {
      this.columnsToDisplay = this._columns.map((item: Column) => item.value);
    }
  
    updatedFn(value: string) {
      this.updated.emit(value);
    }
  
  }
  

我添加了,trackBy因为每当我打字时我都会失去对输入的关注。现在有了trackBy,我可以自由输入,它调度动作,然后我使用reducer 对状态进行更改,然后它正确地将新数据发送回表组件:@Input() data/colums是正确的。但是,它不会更新 DOM。我认为这是因为trackBy,但如果我使用这样的东西:

 trackBy(index: number, stuff) {
      return stuff.value;
    }

...它再次失去对输入的关注。

另外,我尝试使用this.cdr.markForCheck()但它没有做任何事情。

尽管有 trackyBy,我如何更新 DOM?

编辑:为了更准确地了解我如何知道它不会更新 DOM -> 在我的减速器中,我更改了另一个@Input data表格单元格的数据值,但尽管包含新数据,但它并没有出现在表格上。

标签: angular-materialngrx

解决方案


我找到了一个解决方案:我在自身中添加了相同trackyBy的内容ngFor

<ng-container [matColumnDef]="column.value" *ngFor="let column of columns; let i = index; trackBy: trackBy"

我还删除了ngOnChangesmarkForCheck()


推荐阅读