When making edits, always remember to create a copy of the element. You have two options:
1.- Use [ngModel] with the copy, and update the value accordingly
2.- Use [ngModel] with the original element, and cancel by assigning the copied value back
To create a copy, make sure to use the spread operator to avoid assigning the same object to multiple variables.
this.oldValue={...element}
If you prefer editing one row at a time, consider using an unique variable like editIndex
instead of keeping track in an array whether a row is in edit mode or not.
editIndex:number=-1;
editCompanyDetails(details,i) {
this.editIndex=i;
}
In this approach, I choose to edit the "copy" by declaring a variable newValue
.
newValue:any;
editCompanyDetails(details,i) {
this.editIndex=i;
this.newValue={...details}
}
Take note that the mat-form field cannot be used both in edit mode and read-only mode simultaneously. Therefore, separate form fields are needed for element and newValue.
<!-- Separated form fields for element and newValue -->
The update and cancel functions should look like this:
updateCompanyDetails(i){
this.dataSourceCompanyDetails.data[i]={...this.newValue}
this.editIndex=-1;
}
discardCompanyDetails(){
this.editIndex=-1;
}
You can refer to this forked stackbliz for implementation details.
A check has been added in the edit function to prompt if changes will be lost when editing another field while already editing one (not in stackblitz).
editCompanyDetails(details,i) {
if (this.editIndex!=i && this.editIndex!=-1)
{
const data=dataSourceCompanyDetails.data[this.editIndex]
if (data.status!=this.newValue.status || data.companyName!=this.newValue.companyName){
..prompt about losing changes..
}
}
this.editIndex=i;
this.newValue={...details}
}
Updated: Another approach involves declaring a variable oldValue, accessing the table using ViewChild, and ensuring to call renderRows when cancelling the edit.
@ViewChild('table') table:MatTable<any>
oldValue:any;
Function updates as follows:
editCompanyDetails(details,i) {
this.editIndex=i;
this.oldValue={...details}
}
updateCompanyDetails(){
this.editIndex=-1;
}
discardCompanyDetails(i){
this.dataSourceCompanyDetails.data[i]={...this.oldValue}
this.editIndex=-1;
this.table.renderRows()
}
Remember to change [NgModel] to [ngModel] for consistency. Check out the updated implementation in this new stackblitz.