1

I am working on a scenario where I have created a table component which can be plugged into any html template. We can pass different data to it and show.

// table component 
<tbody *ngIf="tableData">

        <tr class="row">
            <td>{{ 'LABEL.DAY' | translate }}</td>
            <td *ngFor="let data of tableData.timesheetInputs.timesheetDays | dayfilterpipe:'DAY' ">
                <input [ngModel] ="data.amount" #day="ngModel" (keypress)="_keyPress($event)" (ngModelChange)="data.amount=$event" (ngModelChange)="timesheetHourChanged(data.amount,'DAY')" [disabled]="inputViewState && !isEditable" [ngClass]="{'is-invalidTimeEntry': (data.amount === '') || ((data.amount)%(0.25) != 0)  || (data.amount > 24) }" />

            </td>
            <td>{{totalDayHour}}</td>
        </tr>

        <tr class="row">
            <td>{{ 'LABEL.NIGHT' | translate }}</td>
            <td *ngFor="let data of tableData.timesheetInputs.timesheetDays | dayfilterpipe:'NIGHT' ">
                <input  [(ngModel)] ="data.amount" #day1="ngModel" (ngModelChange)="timesheetHourChanged(data.amount, 'NIGHT')" [disabled]="inputViewState && !isEditable" [ngClass]="{'is-invalidTimeEntry': (data.amount === '') || ((data.amount)%(0.25) != 0) || (data.amount > 8) }" />
            </td>
            <td>{{totalNightHour}}</td>
        </tr>

</tbody>

And in a parent component it can be invoked like this :

 //first component
 <timesheet-table [tableData]="weekData" #timesheetTable [inputViewState]="statusVisibility"></timesheet-table>

//second component
 <timesheet-table [tableData]="editableWeekData" #timesheetTable   [inputViewState]="statusVisibility" [isEditable]="editable"></timesheet-table>

The issue I am facing is the lower table

 <timesheet-table [tableData]="editableWeekData" #timesheetTable [inputViewState]="statusVisibility" [isEditable]="editable"></timesheet-table>

it can be edited and by changing any cell should not affect the first timesheet-table component which is disabled. But somehow it is happening, whenever I change any field it changes in both the tables.

It seems some issue in using ngModel correctly. I might have missed something.

What can be the best possible way to avoid this issue. I don't want to create another component. I want to reuse the existing table component.

Abhinay Pandey
  • 73
  • 3
  • 13

1 Answers1

0

I assume weekData and editableWeekData is the same object instance.

If you have code like

this.weekData = [ /* some data */ ];
this.editableWeekData = this.weekData;

then both tables will get the same array. When one table modifies the array, the other table sees these changes, because it's the same array (or object)

As a workaround you need a deep clone of the data. See also Deep clone in TypeScript (preserving types)

Community
  • 1
  • 1
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • I am setting data like this : this.editableWeekData = Object.assign({},data); this.weekData = Object.assign({},data); Searched for deep cloning and they suggested me this solution – Abhinay Pandey Jan 19 '17 at 08:50
  • That clones only one level "deep". Just try with two objects that are created independently and if there still is interaction between these tables, then it's something else, but if this makes it work as expected, then the problem is your cloning. – Günter Zöchbauer Jan 19 '17 at 08:53
  • getting [data] from a service and I want to use weekData and editableWeekData independently where each one is copy of [data] – Abhinay Pandey Jan 19 '17 at 08:57
  • I get that. At first you should ensure this is the root cause of your problem mentioned in your question. If that is settled, then you need to fix cloning. – Günter Zöchbauer Jan 19 '17 at 08:58
  • 1
    got this working by using a custom implementation of deep copy. thanks for the suggestion. found this on http://stackoverflow.com/questions/36124363/deep-copying-objects-in-angular2 – Abhinay Pandey Jan 19 '17 at 09:02