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
我正在使用 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