Skip to content

Commit 154892f

Browse files
committed
fix(grid,perf): don't emit multiple events for group row selection
BEHAVIOR CHANGE: row selection even is now emitted only once for the entire group selected as intended. `added` and `removed` arrays in args contain all affected rows Closes #9250
1 parent 61b2aa2 commit 154892f

File tree

6 files changed

+63
-20
lines changed

6 files changed

+63
-20
lines changed

projects/igniteui-angular/src/lib/grids/common/events.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,11 @@ export interface IColumnResizingEventArgs extends IColumnResizeEventArgs, Cancel
8383
}
8484

8585
export interface IRowSelectionEventArgs extends CancelableEventArgs, IBaseEventArgs {
86-
oldSelection: any[];
86+
readonly oldSelection: any[];
8787
newSelection: any[];
88-
added: any[];
89-
removed: any[];
90-
event?: Event;
88+
readonly added: any[];
89+
readonly removed: any[];
90+
readonly event?: Event;
9191
}
9292

9393
export interface IColumnSelectionEventArgs extends CancelableEventArgs, IBaseEventArgs {

projects/igniteui-angular/src/lib/grids/grid/grid.groupby.spec.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,9 +1173,15 @@ describe('IgxGrid - GroupBy #grid', () => {
11731173
tick();
11741174
fix.detectChanges();
11751175

1176+
const selectionSpy = spyOn(grid.rowSelected, 'emit');
11761177
GridFunctions.simulateGridContentKeydown(fix, 'Space');
11771178
fix.detectChanges();
11781179

1180+
expect(selectionSpy).toHaveBeenCalledTimes(1);
1181+
const args = selectionSpy.calls.mostRecent().args[0];
1182+
expect(args.added.length).toBe(2);
1183+
expect(grid.selectedRows.length).toEqual(2);
1184+
11791185
for (const key of grRow.groupRow.records) {
11801186
expect(GridSelectionFunctions.verifyRowSelected(grid.gridAPI.get_row_by_key(key)));
11811187
}
@@ -1257,9 +1263,15 @@ describe('IgxGrid - GroupBy #grid', () => {
12571263
tick();
12581264
fix.detectChanges();
12591265

1266+
const selectionSpy = spyOn(grid.rowSelected, 'emit');
12601267
GridFunctions.simulateGridContentKeydown(fix, 'Space');
12611268
fix.detectChanges();
12621269

1270+
expect(selectionSpy).toHaveBeenCalledTimes(1);
1271+
const args = selectionSpy.calls.mostRecent().args[0];
1272+
expect(args.removed.length).toBe(2);
1273+
expect(grid.selectedRows.length).toEqual(0);
1274+
12631275
for (const key of grRow.groupRow.records) {
12641276
expect(GridSelectionFunctions.verifyRowSelected(grid.gridAPI.get_row_by_key(key), false));
12651277
}

projects/igniteui-angular/src/lib/grids/grid/groupby-row.component.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -218,13 +218,9 @@ export class IgxGridGroupByRowComponent implements OnDestroy {
218218
}
219219
event.stopPropagation();
220220
if (this.areAllRowsInTheGroupSelected) {
221-
this.groupRow.records.forEach(row => {
222-
this.gridSelection.deselectRow(this.getRowID(row), event);
223-
});
221+
this.gridSelection.deselectRows(this.groupRow.records.map(x => this.getRowID(x)));
224222
} else {
225-
this.groupRow.records.forEach(row => {
226-
this.gridSelection.selectRowById(this.getRowID(row), false, event);
227-
});
223+
this.gridSelection.selectRows(this.groupRow.records.map(x => this.getRowID(x)));
228224
}
229225
}
230226

projects/igniteui-angular/src/lib/grids/selection/selection.service.ts

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,6 @@ export class IgxGridSelectionService {
438438
const addedRows = allRowIDs.filter((rID) => !this.isRowSelected(rID));
439439
const newSelection = this.rowSelection.size ? this.getSelectedRows().concat(addedRows) : addedRows;
440440
this.indeterminateRows.clear();
441-
this.selectedRowsChange.next();
442441
this.emitRowSelectionEvent(newSelection, addedRows, [], event);
443442
}
444443

@@ -449,10 +448,10 @@ export class IgxGridSelectionService {
449448
}
450449
clearPrevSelection = !this.grid.isMultiRowSelectionEnabled || clearPrevSelection;
451450

452-
const newSelection = clearPrevSelection ? [rowID] : this.getSelectedRows().indexOf(rowID) !== -1 ?
453-
this.getSelectedRows() : [...this.getSelectedRows(), rowID];
454-
const removed = clearPrevSelection ? this.getSelectedRows() : [];
455-
this.selectedRowsChange.next();
451+
const selectedRows = this.getSelectedRows();
452+
const newSelection = clearPrevSelection ? [rowID] : this.rowSelection.has(rowID) ?
453+
selectedRows : [...selectedRows, rowID];
454+
const removed = clearPrevSelection ? selectedRows : [];
456455
this.emitRowSelectionEvent(newSelection, [rowID], removed, event);
457456
}
458457

@@ -463,11 +462,44 @@ export class IgxGridSelectionService {
463462
}
464463
const newSelection = this.getSelectedRows().filter(r => r !== rowID);
465464
if (this.rowSelection.size && this.rowSelection.has(rowID)) {
466-
this.selectedRowsChange.next();
467465
this.emitRowSelectionEvent(newSelection, [], [rowID], event);
468466
}
469467
}
470468

469+
/** Select the specified rows and emit event. */
470+
public selectRows(keys: any[], clearPrevSelection?: boolean, event?): void {
471+
if (!this.grid.isMultiRowSelectionEnabled) {
472+
return;
473+
}
474+
475+
const rowsToSelect = keys.filter(x => !this.isRowDeleted(x) && !this.rowSelection.has(x));
476+
if (!rowsToSelect.length && !clearPrevSelection) {
477+
// no valid/additional rows to select and no clear
478+
return;
479+
}
480+
481+
const selectedRows = this.getSelectedRows();
482+
const newSelection = clearPrevSelection ? rowsToSelect : [...selectedRows, ...rowsToSelect];
483+
const keysAsSet = new Set(rowsToSelect);
484+
const removed = clearPrevSelection ? selectedRows.filter(x => !keysAsSet.has(x)) : [];
485+
this.emitRowSelectionEvent(newSelection, rowsToSelect, removed, event);
486+
}
487+
488+
public deselectRows(keys: any[], event?): void {
489+
if (!this.rowSelection.size) {
490+
return;
491+
}
492+
493+
const rowsToDeselect = keys.filter(x => this.rowSelection.has(x));
494+
if (!rowsToDeselect.length) {
495+
return;
496+
}
497+
498+
const keysAsSet = new Set(rowsToDeselect);
499+
const newSelection = this.getSelectedRows().filter(r => !keysAsSet.has(r));
500+
this.emitRowSelectionEvent(newSelection, [], rowsToDeselect, event);
501+
}
502+
471503
/** Select specified rows. No event is emitted. */
472504
public selectRowsWithNoEvent(rowIDs: any[], clearPrevSelection?): void {
473505
if (clearPrevSelection) {
@@ -508,7 +540,6 @@ export class IgxGridSelectionService {
508540

509541
const added = this.getRowIDs(rows).filter(rID => !this.isRowSelected(rID));
510542
const newSelection = this.getSelectedRows().concat(added);
511-
this.selectedRowsChange.next();
512543
this.emitRowSelectionEvent(newSelection, added, [], event);
513544
}
514545

src/app/grid-groupby/grid-groupby.sample.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
<div class="wrapper">
7070
<h3>Selection Performance</h3>
7171
<igx-grid [data]="data2" [allowFiltering]="true" cellSelection="none" width="1200px"
72-
height="500px" rowSelection="multiple" [groupingExpressions]="perfGrpExpr">
72+
height="500px" rowSelection="multiple" [groupingExpressions]="perfGrpExpr" (rowSelected)="rowSelectionChanged($event)">
7373
<igx-column field="STATUS" header="Status" width="200px" [groupable]="true" [sortable]="true">
7474
</igx-column>
7575
<igx-column field="FIELD" header="Field" width="200px" [groupable]="true" [sortable]="true">

src/app/grid-groupby/grid-groupby.sample.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Component, ViewChild, OnInit, Inject } from '@angular/core';
33

44
import {
55
IgxGridComponent, SortingDirection, ISortingExpression,
6-
DefaultSortingStrategy, DisplayDensity, IDisplayDensityOptions, DisplayDensityToken, GridSummaryPosition, GridSummaryCalculationMode
6+
DefaultSortingStrategy, DisplayDensity, IDisplayDensityOptions, DisplayDensityToken, GridSummaryPosition, GridSummaryCalculationMode, IRowSelectionEventArgs
77
} from 'igniteui-angular';
88

99
@Component({
@@ -33,7 +33,7 @@ export class GridGroupBySampleComponent implements OnInit {
3333
constructor(@Inject(DisplayDensityToken) public displayDensityOptions: IDisplayDensityOptions) { }
3434

3535
public ngOnInit(): void {
36-
for (let i = 0; i < 60; i++) {
36+
for (let i = 0; i < 2500; i++) {
3737
this.data2.push(...Array(10).fill({ STATUS: 'A', FIELD: 'some text' }));
3838
this.data2.push(...Array(10).fill({ STATUS: 'B', FIELD: 'some text' }));
3939
this.data2.push(...Array(10).fill({ STATUS: 'C', FIELD: 'some text' }));
@@ -174,4 +174,8 @@ export class GridGroupBySampleComponent implements OnInit {
174174
this.grid1.showGroupArea = !this.grid1.showGroupArea;
175175
this.grid1.cdr.detectChanges();
176176
}
177+
178+
public rowSelectionChanged(e: IRowSelectionEventArgs) {
179+
console.log(e);
180+
}
177181
}

0 commit comments

Comments
 (0)