Angular - (размытие) событие на <td>срабатывает и обновляет значение в соседней ячейке - PullRequest
0 голосов
/ 01 октября 2019

Я использую Angular 8, я создал 2-мерный массив (элементы), а затем динамически сгенерировал HTML-таблицу с 2 * циклами ngFor.

<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>

Моя ячейка таблицы является редактируемыми элементами "td" иЯ устанавливаю номера строк и столбцов с помощью пользовательских атрибутов «r» и «c».

Значения в ячейках обновляются правильно, когда я изменяю обновление ячейки в моем двумерном массиве.

Затем я добавил событие (размытие), чтобы обнаружить изменения в «td»,Событие запускается, как и ожидалось, но я получаю странное поведение при попытке обновить значение в массиве на основе обновления.

Моя функция updated () выглядит следующим образом:

  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]);
  }

Моя таблица выглядит следующим образом

enter image description here

Затем я ввожу значение в ячейку "A1" (поэтому элемент 1 моегомассив), а затем щелкните другую ячейку (неважно, какую), чтобы вызвать событие «onBlur ()»

В функции, вызванной событием, я записываю введенное значение в массив. Массив в фоновом режиме получает правильные значения, но введенное мной значение копируется в следующую ячейку справа.

enter image description here

Я добавил несколькоconsole.log в "updated ()", и я получаю довольно странные значения. enter image description here

Когда я печатаю «td», он показывает c = «2», но когда я запрашиваю атрибут в следующей строке, я получаю c = «1». Массив в серверной части, похоже, корректно обновляется как [ 1 ] [ 1 ] = 1 и [ 1 ] [ 2 ] = 0

Я заметил, что проблема возникает только при первой смене ячейки. Если я изменю A1, B1 будет иметь то же значение. Но если я снова изменю A1, проблема больше не повторится.

Я воссоздал проблему в этом стеке:

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

Я также пытался использоватьсобытие "focusout", но я получаю такое же поведение. Если есть лучший / более простой способ добиться двустороннего связывания данных, не стесняйтесь указывать мне в другом направлении.

1 Ответ

1 голос
/ 01 октября 2019

Я полагаю, что это просто механизм обнаружения угловых изменений, который не может дифференцировать все привязки. Таким образом, вам нужно предоставить 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}`
  }

}

Вот ссылка на рабочий пример: https://stackblitz.com/edit/angular-maggnl

...