Skip to content

Commit 5053978

Browse files
authored
Merge pull request #7511 from IgniteUI/pbozhinov/fix-7416
refactor(*): Moves remote virtualization methods to supported grids
2 parents 66957bd + ae98260 commit 5053978

File tree

10 files changed

+172
-29
lines changed

10 files changed

+172
-29
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ All notable changes for each version of this project will be documented in this
1313
- Added `closeOnEscapeKey` - with it, the dialog can be allowed or prevented from closing when `Esc` is pressed.
1414
- `IgxNavbar`:
1515
- **Breaking Changes** - The `igx-action-icon` has been renamed to `igx-navbar-action`. It should get renamed in your components via `ng update`;
16+
- `igxGrid`
17+
- Added `onScroll` event, which is emitted when the grid is scrolled vertically or horizontally.
18+
- `igxTreeGrid`
19+
- Removed `onDataPreLoad` event as it is specific for remote virtualization implementation, which is not supported for the `igxTreeGrid`. A more generic `onScroll` event is exposed and can be used instead.
20+
1621
### New Features
1722
- `IgxGridState` directive
1823
- Added support for expansion states, column selection and row pinning.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"$schema": "../../common/schema/binding.schema.json",
3+
"changes": [
4+
{
5+
"name": "onDataPreLoad",
6+
"replaceWith": "onScroll",
7+
"owner": {
8+
"selector": "igx-tree-grid",
9+
"type": "component"
10+
}
11+
}
12+
]
13+
}

projects/igniteui-angular/migrations/update-10_1_0/index.spec.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,18 @@ describe('Update 10.1.0', () => {
105105
.toEqual(expectedFileContent);
106106
});
107107

108+
it('should replace onDataPreLoad with onScroll ', async () => {
109+
appTree.create(
110+
`/testSrc/appPrefix/component/tree-grid.component.html`,
111+
'<igx-tree-grid (onDataPreLoad)="handleEvent($event)"></igx-tree-grid>'
112+
);
113+
114+
const tree = await schematicRunner.runSchematicAsync('migration-16', {}, appTree)
115+
.toPromise();
116+
117+
expect(tree.readContent('/testSrc/appPrefix/component/tree-grid.component.html'))
118+
.toEqual('<igx-tree-grid (onScroll)="handleEvent($event)"></igx-tree-grid>');
119+
120+
});
121+
108122
});

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,3 +150,15 @@ export interface IPinRowEventArgs extends IBaseEventArgs {
150150
/** Whether or noy the row is pinned or unpinned. */
151151
readonly isPinned: boolean;
152152
}
153+
154+
/**
155+
* Event emitted when a grid is scrolled.
156+
*/
157+
export interface IGridScrollEventArgs extends IBaseEventArgs {
158+
/** The scroll direction - vertical or horizontal. */
159+
direction: string;
160+
/** The original browser scroll event. */
161+
event: Event;
162+
/** The new scroll position */
163+
scrollPosition: number;
164+
}

projects/igniteui-angular/src/lib/grids/grid-base.directive.ts

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,8 @@ import {
138138
ICellPosition,
139139
IRowToggleEventArgs,
140140
IColumnSelectionEventArgs,
141-
IPinRowEventArgs
141+
IPinRowEventArgs,
142+
IGridScrollEventArgs
142143
} from './common/events';
143144
import { IgxAdvancedFilteringDialogComponent } from './filtering/advanced-filtering/advanced-filtering-dialog.component';
144145
import { GridType } from './common/grid.interface';
@@ -360,6 +361,17 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
360361
@Output()
361362
public advancedFilteringExpressionsTreeChange = new EventEmitter<IFilteringExpressionsTree>();
362363

364+
/**
365+
* Emitted when grid is scrolled horizontally/vertically.
366+
* @example
367+
* ```html
368+
* <igx-grid #grid [data]="localData" [height]="'305px'" [autoGenerate]="true"
369+
* (onScroll)="onScroll($event)"></igx-grid>
370+
* ```
371+
*/
372+
@Output()
373+
public onScroll = new EventEmitter<IGridScrollEventArgs>();
374+
363375
/**
364376
* Gets/Sets the advanced filtering state.
365377
* @example
@@ -1281,16 +1293,6 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
12811293
@Output()
12821294
public onRowDeleted = new EventEmitter<IRowDataEventArgs>();
12831295

1284-
/**
1285-
* Emitted when a new chunk of data is loaded from virtualization.
1286-
* @example
1287-
* ```typescript
1288-
* <igx-grid #grid [data]="localData" [autoGenerate]="true" (onDataPreLoad)='handleDataPreloadEvent()'></igx-grid>
1289-
* ```
1290-
*/
1291-
@Output()
1292-
public onDataPreLoad = new EventEmitter<IForOfState>();
1293-
12941296
/**
12951297
* Emitted when column is resized.
12961298
* @remarks
@@ -2663,6 +2665,12 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
26632665
this.disableTransitions = false;
26642666

26652667
this.hideOverlays();
2668+
const args: IGridScrollEventArgs = {
2669+
direction: 'vertical',
2670+
event: event,
2671+
scrollPosition: this.verticalScrollContainer.scrollPosition
2672+
};
2673+
this.onScroll.emit(args);
26662674
}
26672675

26682676
private horizontalScrollHandler = (event) => {
@@ -2678,6 +2686,8 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
26782686
});
26792687

26802688
this.hideOverlays();
2689+
const args: IGridScrollEventArgs = { direction: 'horizontal', event: event, scrollPosition: this.headerContainer.scrollPosition };
2690+
this.onScroll.emit(args);
26812691
}
26822692

26832693
/**
@@ -3220,13 +3230,6 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
32203230
});
32213231
}
32223232

3223-
/**
3224-
* @hidden @internal
3225-
*/
3226-
public dataLoading(event) {
3227-
this.onDataPreLoad.emit(event);
3228-
}
3229-
32303233
/**
32313234
* Toggles the specified column's visibility.
32323235
* @example

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

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1597,6 +1597,48 @@ describe('IgxGrid Component Tests #grid', () => {
15971597

15981598
expect(grid.verticalScrollContainer.getScroll().scrollTop).toEqual(200);
15991599
});
1600+
1601+
it('should emit onScroll event when scrolling horizontally/vertically', async() => {
1602+
const fix = TestBed.createComponent(IgxGridDefaultRenderingComponent);
1603+
fix.componentInstance.initColumnsRows(30, 10);
1604+
fix.detectChanges();
1605+
1606+
const grid = fix.componentInstance.grid;
1607+
grid.height = '300px';
1608+
grid.width = '300px';
1609+
fix.detectChanges();
1610+
1611+
spyOn(grid.onScroll, 'emit').and.callThrough();
1612+
let verticalScrollEvent;
1613+
let horizontalScrollEvent;
1614+
grid.verticalScrollContainer.getScroll().addEventListener('scroll', (evt) => verticalScrollEvent = evt);
1615+
grid.headerContainer.getScroll().addEventListener('scroll', (evt) => horizontalScrollEvent = evt);
1616+
1617+
grid.navigateTo(20, 0);
1618+
fix.detectChanges();
1619+
await wait(100);
1620+
fix.detectChanges();
1621+
1622+
expect(grid.onScroll.emit).toHaveBeenCalledTimes(1);
1623+
expect(grid.onScroll.emit).toHaveBeenCalledWith({
1624+
direction: 'vertical',
1625+
scrollPosition: grid.verticalScrollContainer.getScrollForIndex(20, true),
1626+
event: verticalScrollEvent
1627+
});
1628+
1629+
grid.navigateTo(20, 6);
1630+
fix.detectChanges();
1631+
await wait(100);
1632+
fix.detectChanges();
1633+
1634+
expect(grid.onScroll.emit).toHaveBeenCalledTimes(2);
1635+
expect(grid.onScroll.emit).toHaveBeenCalledWith({
1636+
direction: 'horizontal',
1637+
scrollPosition: grid.headerContainer.getScrollForIndex(6, true),
1638+
event: horizontalScrollEvent
1639+
});
1640+
1641+
});
16001642
});
16011643

16021644
describe('IgxGrid - Integration with other Igx Controls', () => {

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { IGroupByRecord } from '../../data-operations/groupby-record.interface';
1212
import { IgxGroupByRowTemplateDirective, IgxGridDetailTemplateDirective } from './grid.directives';
1313
import { IgxGridGroupByRowComponent } from './groupby-row.component';
1414
import { IGroupByExpandState } from '../../data-operations/groupby-expand-state.interface';
15+
import { IForOfState } from '../../directives/for-of/for_of.directive';
1516
import { IBaseChipEventArgs, IChipClickEventArgs, IChipKeyDownEventArgs } from '../../chips/chip.component';
1617
import { IChipsAreaReorderEventArgs } from '../../chips/chips-area.component';
1718
import { IgxColumnComponent } from '../columns/column.component';
@@ -168,6 +169,16 @@ export class IgxGridComponent extends IgxGridBaseDirective implements GridType,
168169
this._filteredData = value;
169170
}
170171

172+
/**
173+
* Emitted when a new chunk of data is loaded from virtualization.
174+
* @example
175+
* ```typescript
176+
* <igx-grid #grid [data]="localData" [autoGenerate]="true" (onDataPreLoad)='handleDataPreloadEvent()'></igx-grid>
177+
* ```
178+
*/
179+
@Output()
180+
public onDataPreLoad = new EventEmitter<IForOfState>();
181+
171182
/**
172183
* Gets/Sets the total number of records in the data source.
173184
* @remarks
@@ -1038,6 +1049,13 @@ export class IgxGridComponent extends IgxGridBaseDirective implements GridType,
10381049
super.ngDoCheck();
10391050
}
10401051

1052+
/**
1053+
* @hidden @internal
1054+
*/
1055+
public dataLoading(event) {
1056+
this.onDataPreLoad.emit(event);
1057+
}
1058+
10411059
/**
10421060
* @inheritdoc
10431061
*/

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

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import { IgxHierarchicalGridBaseDirective } from './hierarchical-grid-base.direc
3232
import { takeUntil } from 'rxjs/operators';
3333
import { IgxTemplateOutletDirective } from '../../directives/template-outlet/template_outlet.directive';
3434
import { IgxGridSelectionService, IgxGridCRUDService } from '../selection/selection.service';
35+
import { IForOfState } from '../../directives/for-of/for_of.directive';
3536
import { IgxTransactionService } from '../../services/public_api';
3637
import { IgxForOfSyncService, IgxForOfScrollSyncService } from '../../directives/for-of/for_of.sync.service';
3738
import { GridType } from '../common/grid.interface';
@@ -128,8 +129,6 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti
128129
*/
129130
public set filteredData(value) {
130131
this._filteredData = value;
131-
132-
133132
}
134133

135134
/**
@@ -143,6 +142,36 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti
143142
return this._filteredData;
144143
}
145144

145+
/**
146+
* Emitted when a new chunk of data is loaded from virtualization.
147+
* @example
148+
* ```typescript
149+
* <igx-hierarchical-grid [id]="'igx-grid-1'" [data]="Data" [autoGenerate]="true" (onDataPreLoad)="handleEvent()">
150+
* </igx-hierarchical-grid>
151+
* ```
152+
*/
153+
@Output()
154+
public onDataPreLoad = new EventEmitter<IForOfState>();
155+
156+
/**
157+
* Gets/Sets the total number of records in the data source.
158+
* @remarks
159+
* This property is required for remote grid virtualization to function when it is bound to remote data.
160+
* @example
161+
* ```typescript
162+
* const itemCount = this.grid1.totalItemCount;
163+
* this.grid1.totalItemCount = 55;
164+
* ```
165+
*/
166+
set totalItemCount(count) {
167+
this.verticalScrollContainer.totalItemCount = count;
168+
this.cdr.detectChanges();
169+
}
170+
171+
get totalItemCount() {
172+
return this.verticalScrollContainer.totalItemCount;
173+
}
174+
146175
/**
147176
* Sets if all immediate children of the `IgxHierarchicalGridComponent` should be expanded/collapsed.
148177
* Defult value is false.
@@ -362,6 +391,13 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti
362391
super.ngAfterContentInit();
363392
}
364393

394+
/**
395+
* @hidden @internal
396+
*/
397+
public dataLoading(event) {
398+
this.onDataPreLoad.emit(event);
399+
}
400+
365401
/** @hidden */
366402
public featureColumnsWidth() {
367403
return super.featureColumnsWidth(this.headerHierarchyExpander);

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

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { IgxRowIslandComponent } from './row-island.component';
88
import { wait, UIInteractions } from '../../test-utils/ui-interactions.spec';
99
import { By } from '@angular/platform-browser';
1010
import { first, delay } from 'rxjs/operators';
11-
import { setupHierarchicalGridScrollDetection } from '../../test-utils/helper-utils.spec';
11+
import { setupHierarchicalGridScrollDetection, resizeObserverIgnoreError } from '../../test-utils/helper-utils.spec';
1212
import { FilteringExpressionsTree } from '../../data-operations/filtering-expressions-tree';
1313
import { FilteringLogic } from '../../data-operations/filtering-expression.interface';
1414
import { IgxStringFilteringOperand } from '../../data-operations/filtering-condition';
@@ -280,7 +280,8 @@ describe('IgxHierarchicalGrid Virtualization #hGrid', () => {
280280
.not.toBe(-1);
281281
});
282282

283-
it('should update scroll height after expanding/collapsing row in a nested child grid that has no height.', async () => {
283+
it('should update scroll height after expanding/collapsing row in a nested child grid that has no height.', async () => {
284+
resizeObserverIgnoreError();
284285
fixture.componentInstance.data = [
285286
{ ID: 0, ChildLevels: 3, ProductName: 'Product: A0 ' },
286287
{ ID: 1, ChildLevels: 3, ProductName: 'Product: A0 ' },
@@ -299,10 +300,10 @@ it('should update scroll height after expanding/collapsing row in a nested child
299300
expect(scrHeight).toBe(0);
300301

301302
(hierarchicalGrid.dataRowList.toArray()[2].nativeElement.children[0] as HTMLElement).click();
302-
await wait(100);
303+
await wait(200);
303304
fixture.detectChanges();
304305
hierarchicalGrid.verticalScrollContainer.scrollNext();
305-
await wait(100);
306+
await wait(200);
306307
fixture.detectChanges();
307308

308309
const childGrid1 = hierarchicalGrid.hgridAPI.getChildGrids(false)[0];
@@ -311,14 +312,14 @@ it('should update scroll height after expanding/collapsing row in a nested child
311312

312313
// expand
313314
(childGrid1.dataRowList.toArray()[0].nativeElement.children[0] as HTMLElement).click();
314-
await wait(100);
315+
await wait(200);
315316
fixture.detectChanges();
316317
scrHeight = hierarchicalGrid.verticalScrollContainer.getScroll().scrollHeight;
317318
expect(scrHeight).toBe(3 * 51 + childGrid1.nativeElement.closest('.igx-grid__tr-container').offsetHeight - 1);
318319

319320
// collapse
320321
(childGrid1.dataRowList.toArray()[0].nativeElement.children[0] as HTMLElement).click();
321-
await wait(100);
322+
await wait(200);
322323
fixture.detectChanges();
323324
scrHeight = hierarchicalGrid.verticalScrollContainer.getScroll().scrollHeight;
324325
expect(scrHeight).toBe(3 * 51 + childGrid1.nativeElement.closest('.igx-grid__tr-container').offsetHeight - 1);
@@ -336,7 +337,7 @@ it('should update scroll height after expanding/collapsing row in a nested child
336337
expect(childRowComponent.index).toBe(4);
337338

338339
hierarchicalGrid.verticalScrollContainer.scrollNext();
339-
await wait(100);
340+
await wait(200);
340341
fixture.detectChanges();
341342
childRowComponent = fixture.debugElement.query(By.css('igx-child-grid-row')).componentInstance;
342343
expect(childRowComponent.rowData.rowID).toBe('3');

projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.html

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,7 @@
107107
| treeGridSummary:hasSummarizedColumns:summaryCalculationMode:summaryPosition:id:pipeTrigger:summaryPipeTrigger
108108
| gridRowPinning:id:false:pipeTrigger"
109109
let-rowIndex="index" [igxForScrollOrientation]="'vertical'" [igxForScrollContainer]='verticalScroll'
110-
[igxForContainerSize]='calcHeight' [igxForItemSize]="renderedRowHeight" #verticalScrollContainer
111-
(onChunkPreload)="dataLoading($event)">
110+
[igxForContainerSize]='calcHeight' [igxForItemSize]="renderedRowHeight" #verticalScrollContainer>
112111
<ng-template [igxTemplateOutlet]='isSummaryRow(rowData) ? summary_template : record_template'
113112
[igxTemplateOutletContext]='getContext(rowData, rowIndex, false)'
114113
(onCachedViewLoaded)='cachedViewLoaded($event)'>

0 commit comments

Comments
 (0)