I am working with a datatable, chart, and a label that shows the latest added value.
- The table and chart display time-series data for the last 30 minutes, including the timestamp and a random numerical value between 0 and 999.
- Every 10 seconds, a new data object is added to the array while the oldest one is removed, ensuring that only the last 30 minutes of data are visible. The Latest Value label reflects the most recent addition.
My problem arises when attempting to edit rows in the table. After editing a cell by inputting numbers, if I cancel the edit without saving (by clicking X), the values in the table and chart update after 10 seconds. This behavior is unexpected as the edit was canceled. Similarly, just typing in the input field without saving or canceling the edit also triggers changes in the displayed values.
I suspect this issue has to do with two-way binding in the table, but I am unsure how to resolve it.
I tried the following solution, but encountered the same results:
clonedData = [];
ngOnChanges() {
this.clonedData = [...tableData]}
In the HTML table, instead of using tableData for the value, I attempted using clonedData as shown in the code snippet above.
Here is a link to the StackBlitz project: https://stackblitz.com/edit/angular-43vasb?file=src%2Fapp%2Fmain%2Ftable%2Ftable.component.ts,src%2Fapp%2Fmain%2Fmain.component.ts,src%2Fapp%2Finterface.ts,src%2Fapp%2Fdata.service.ts,src%2Fapp%2Fmain%2Ftable%2Ftable.component.html
Table TypeScript code:
export class TableComponent {
@Input() tableData: IData[] = [];
editedData: { [s: string]: IData } = {};
constructor(private dataService: DataService) {}
onRowEditInit(data: IData) {
this.editedData[data.id] = { ...data };
console.log(this.editedData[data.id]);
}
editRow(data: IData, row: any) {
this.tableData[row] = data;
this.dataService.setData(this.tableData);
delete this.editedData[data.id];
}
onRowEditCancel(data: IData, row: number) {
this.tableData[row] = this.editedData[data.id];
delete this.editedData[data.id];
}
}
Table HTML code:
<div class="container">
<p-table
[value]="tableData"
dataKey="id"
editMode="row"
scrollHeight="flex"
styleClass="p-datatable-gridlines"
[rows]="8"
[scrollable]="true"
>
<ng-template pTemplate="header">
<tr>
<th class="time">Time</th>
<th class="value">Value</th>
<th class="action"></th>
</tr>
</ng-template>
<ng-template
pTemplate="body"
let-data
let-editing="editing"
let-ri="rowIndex"
>
<tr [pEditableRow]="data">
<td class="p-column-title">
<p-cellEditor>
<ng-template pTemplate="input">
<input pInputText type="text" [(ngModel)]="data.time" />
</ng-template>
<ng-template pTemplate="output">
{{ data.time | date : "yyyy-MM-dd HH:mm:ss" }}
</ng-template>
</p-cellEditor>
</td>
<td>
<p-cellEditor>
<ng-template pTemplate="input">
<input pInputText type="number" [(ngModel)]="data.value" />
</ng-template>
<ng-template pTemplate="output">
{{ data.value | number : "1.2-2" }}
</ng-template>
</p-cellEditor>
</td>
<td class="action-button">
<div class="flex align-items-center justify-content-center gap-2">
<button
*ngIf="!editing"
pButton
pRipple
type="button"
(click)="onRowEditInit(data)"
pInitEditableRow
icon="pi pi-pencil"
class="p-button-rounded p-button-text"
></button>
<button
*ngIf="editing"
pButton
pRipple
(click)="editRow(data, ri)"
type="button"
pSaveEditableRow
icon="pi pi-check"
class="p-button-rounded p-button-text p-button-success mr-2"
></button>
<button
*ngIf="editing"
pButton
pRipple
(click)="onRowEditCancel(data, ri)"
type="button"
pCancelEditableRow
icon="pi pi-times"
class="p-button-rounded p-button-text p-button-danger"
></button>
</div>
</td>
</tr>
</ng-template>
</p-table>
</div>