angular2-grid icon indicating copy to clipboard operation
angular2-grid copied to clipboard

Binding [(ngGridItem)] by array index causes trouble

Open ScallyGames opened this issue 8 years ago • 2 comments

Continuing from #215: When referencing the [(ngGridItem)] binding by index, deleting items from the array causes wrong items to be deleted and others to be duplicated when cascading up.

Example code (reduced itemcount for brevity)

this.items = [
   {'name': '1', 'col': 1, 'row': 1, 'sizex': 1, 'sizey': 1 },
   {'name': '2', 'col': 2, 'row': 1, 'sizex': 1, 'sizey': 1 },
   {'name': '3', 'col': 1, 'row': 2, 'sizex': 1, 'sizey': 1 },
   {'name': '4', 'col': 2, 'row': 2, 'sizex': 1, 'sizey': 1 }
]

removeWidget(index: number): void
{
   this.items.splice(index, 1);
}

<div [ngGrid]="gridconfig">
    <div *ngFor="let item of items; let i = index" [(ngGridItem)]="items[i]">
        <button (click)="removeWidget(i)">Remove</button>
    </div>
</div>

Behaviour:

0|1|2
3|4|5
6|7

Delete 1

0|4|2
3|4|5
6|7
-|7

Fix/Workaround: Binding to an object property fixes this problem (direct bind to item is prohibited as item is a local variable).

this.items = [
   { config: {'name': '1', 'col': 1, 'row': 1, 'sizex': 1, 'sizey': 1 } },
   { config: {'name': '2', 'col': 2, 'row': 1, 'sizex': 1, 'sizey': 1 } },
   { config: {'name': '3', 'col': 1, 'row': 2, 'sizex': 1, 'sizey': 1 } },
   { config: {'name': '4', 'col': 2, 'row': 2, 'sizex': 1, 'sizey': 1 } }
]

<div [ngGrid]="gridconfig">
    <div *ngFor="let item of items; let i = index" [(ngGridItem)]="item.config">
        <button (click)="removeWidget(i)">Remove</button>
    </div>
</div>

While this might be not worth fixing, it would at least be a good idea to add some kind of Troubleshooting section to the readme to document that you have to bind [(ngGridItem)] to the property of an object instead of accessing it by index.

ScallyGames avatar Mar 10 '17 13:03 ScallyGames

In the first example, why aren't you doing [(ngGridItem)]="item"? That's how I would bind to the array item, rather than by index. I can investigate why it does this, but it seems like a misuse of the ngForOf directive.

BTMorton avatar May 05 '17 23:05 BTMorton

That is because you cannot two-way bind on the loop-scoped variable (angular throws an arrow). The solution is to bind on object properties but it should state so in the docs (or even better show a console warning if not used correctly) or this bug should be fixed.

ScallyGames avatar May 06 '17 10:05 ScallyGames