Angular - <td> 上的(模糊)事件被触发并更新相邻单元格中的值

Angular - (blur) event on <td> gets fired and updates value in adjacent cell

我正在使用 Angular 8,我创建了一个二维数组(元素),然后动态生成了一个带有 2 个 *ngFor 循环的 html table。

<table>
  <tr *ngFor="let el of elements, let row = index">
    <td *ngFor="let e of el, let col = index" [attr.r] = "row" [attr.c] = "col" contenteditable="true" (blur)="changed($event)">{{ e }}</td>
  </tr>
</table>

我的 table 单元格是 editable "td" 元素,我使用自定义属性 "r" 和 "c" 设置行号和列号。

当我更改二维数组中的更新单元格时,单元格中的值得到正确更新。

然后我添加了“(blur)”事件来检测 "td" 中的变化。该事件按预期触发,但在尝试根据更新更新数组中的值时出现奇怪的行为。

我的 changed() 函数如下:

  changed(event) {
    console.log(event);
    let td = (event['target']) as HTMLTableDataCellElement;
    console.log(td);
    const row = td.getAttribute('r');
    const col = td.getAttribute('c');
    console.log('r: ' + row);
    console.log('c: ' + col);
    console.log('value: ' + td.innerHTML);
    this.elements[row][col] = td.innerHTML;
    console.log('elements[1][1]: ' + this.elements[1][1]);
    console.log('elements[1][2] ' + this.elements[1][2]);
    console.log('elements[2][1]: ' + this.elements[2][1]);
  }

我的 table 看起来像下面这样

然后我在单元格 "A1" 中输入一个值(所以我的数组的元素 1)然后单击另一个单元格(无论哪个单元格)以触发 "onBlur()"事件

在事件触发的函数中,我正在将输入的值写回数组。背景中的数组获得了正确的值,但我输入的值被复制到右侧的下一个单元格。

我在 "changed()" 中添加了几个 console.log,我得到了一些非常奇怪的值。

当我打印 "td" 时,它显示 c="2",但是当我查询下一行的属性时,我得到 c="1"。 后端数组似乎已正确更新为 [1][1] = 1 和 [1][2] = 0

我注意到这个问题只在第一次更改单元格时发生。如果我更改 A1,B1 将具有相同的值。但是如果我再次更改A1,问题就不会再发生了。

我在这个 stackblitz 中重现了这个问题:

https://stackblitz.com/edit/angular-ta82dv

我也尝试过使用 "focusout" 事件,但我得到了相同的行为。如果有 better/easier 实现双向数据绑定的方法,请不要犹豫,为我指出另一个方向。

我想这只是 Angular 无法区分所有绑定的更改检测机制。所以需要提供trackBy函数:

<table>
  <tr *ngFor="let el of elements, let row = index">
    <td *ngFor="let e of el, let col = index; trackBy: trackByIndex(row, col)" [attr.r] = "row" [attr.c] = "col" contenteditable="true" (blur)="changed($event)">{{ e }}</td>
  </tr>
</table>

以及函数:

export class AppComponent  {

  trackByIndex(row, col) {
    return () => `${row}:${col}`
  }

}

这是一个 link 的工作示例:https://stackblitz.com/edit/angular-maggnl