From c028e2a540f3e98c1a298c942d894f1ee538bcfe Mon Sep 17 00:00:00 2001 From: ddaribo Date: Thu, 15 Feb 2024 15:46:21 +0200 Subject: [PATCH] fix(hgrid): do not use h-pipe data when data is set by user --- .../hierarchical-grid.component.ts | 43 +++++++++------- .../hierarchical-grid.spec.ts | 51 +++++++++++++++---- 2 files changed, 66 insertions(+), 28 deletions(-) diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts index dfc662b49c7..0ca419d8529 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts @@ -110,8 +110,8 @@ export class IgxChildGridRowComponent implements AfterViewInit, OnInit { public set data(value: any) { this._data = value; - if (this.hGrid) { - this.hGrid.data = this._data.childGridsData[this.layout.key]; + if (this.hGrid && !this.hGrid.dataSetByUser) { + this.hGrid.setDataInternal(this._data.childGridsData[this.layout.key]); } } @@ -194,7 +194,7 @@ export class IgxChildGridRowComponent implements AfterViewInit, OnInit { public ngOnInit() { const ref = this.container.createComponent(IgxHierarchicalGridComponent, { injector: this.container.injector }); this.hGrid = ref.instance; - this.hGrid.data = this.data.childGridsData[this.layout.key]; + this.hGrid.setDataInternal(this.data.childGridsData[this.layout.key]); this.layout.layoutChange.subscribe((ch) => { this._handleLayoutChanges(ch); }); @@ -385,6 +385,9 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti */ public childLayoutKeys = []; + /** @hidden @internal */ + public dataSetByUser = false; + /** * @hidden */ @@ -442,20 +445,8 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti */ @Input() public set data(value: any[] | null) { - this._data = value || []; - this.summaryService.clearSummaryCache(); - if (!this._init) { - this.validation.updateAll(this._data); - } - if (this.shouldGenerate) { - this.setupColumns(); - this.reflow(); - } - this.cdr.markForCheck(); - if (this.parent && (this.height === null || this.height.indexOf('%') !== -1)) { - // If the height will change based on how much data there is, recalculate sizes in igxForOf. - this.notifyChanges(true); - } + this.setDataInternal(value); + this.dataSetByUser = true; } /** @@ -796,6 +787,24 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti return super.pinRow(rowID, index, row); } + /** @hidden @internal */ + public setDataInternal(value: any) { + this._data = value || []; + this.summaryService.clearSummaryCache(); + if (!this._init) { + this.validation.updateAll(this._data); + } + if (this.shouldGenerate) { + this.setupColumns(); + this.reflow(); + } + this.cdr.markForCheck(); + if (this.parent && (this.height === null || this.height.indexOf('%') !== -1)) { + // If the height will change based on how much data there is, recalculate sizes in igxForOf. + this.notifyChanges(true); + } + } + public override unpinRow(rowID: any): boolean { const row = this.getRowByKey(rowID); return super.unpinRow(rowID, row); diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.spec.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.spec.ts index 1ab5ca6886e..b54fa33859e 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.spec.ts @@ -464,21 +464,24 @@ describe('Basic IgxHierarchicalGrid #hGrid', () => { UIInteractions.simulateClickAndSelectEvent(row.expander); fixture.detectChanges(); - let childGrids = fixture.debugElement.queryAll(By.css('igx-child-grid-row')); - let childGrid = childGrids[0].query(By.css('igx-hierarchical-grid')).componentInstance; + // check by adding multiple rows + for (let i = 0; i < 3; i++) { + let childGrids = fixture.debugElement.queryAll(By.css('igx-child-grid-row')); + let childGrid = childGrids[0].query(By.css('igx-hierarchical-grid')).componentInstance; - fixture.componentInstance.data[0].childData = [...hierarchicalGrid.data[0].childData ?? [], { ID: 10, ProductName: 'New child' }]; - fixture.componentInstance.data = [...fixture.componentInstance.data]; - fixture.detectChanges(); + fixture.componentInstance.data[0].childData = [...hierarchicalGrid.data[0].childData ?? [], { ID: i * 10, ProductName: 'New child' + i.toString() }]; + fixture.componentInstance.data = [...fixture.componentInstance.data]; + fixture.detectChanges(); - childGrids = fixture.debugElement.queryAll(By.css('igx-child-grid-row')); - childGrid = childGrids[0].query(By.css('igx-hierarchical-grid')).componentInstance; + childGrids = fixture.debugElement.queryAll(By.css('igx-child-grid-row')); + childGrid = childGrids[0].query(By.css('igx-hierarchical-grid')).componentInstance; - const length = fixture.componentInstance.data[0].childData.length; - const newRow = childGrid.gridAPI.get_row_by_index(length - 1) as IgxHierarchicalRowComponent; + const length = fixture.componentInstance.data[0].childData.length; + const newRow = childGrid.gridAPI.get_row_by_index(length - 1) as IgxHierarchicalRowComponent; - expect(newRow).not.toBeUndefined(); - expect(childGrid.data).toBe(fixture.componentInstance.data[0].childData); + expect(newRow).not.toBeUndefined(); + expect(childGrid.data).toBe(fixture.componentInstance.data[0].childData); + } }); it('when child width is in percents its width should be update if parent width changes while parent row is collapsed. ', async () => { @@ -1182,6 +1185,32 @@ describe('Basic IgxHierarchicalGrid #hGrid', () => { expect(iconTxt).toBe('unfold_less'); expect(icon.getActive).toBe(false); }); + + it('should keep already expanded child grids\' data when expanding subsequent ones', fakeAsync(() => { + const hierarchicalGrid = fixture.componentInstance.instance; + + fixture.componentInstance.databind(); + fixture.detectChanges(); + + const row0 = hierarchicalGrid.gridAPI.get_row_by_index(0) as IgxHierarchicalRowComponent; + UIInteractions.simulateClickAndSelectEvent(row0.expander); + fixture.detectChanges(); + tick(); + + let childGrids = hierarchicalGrid.gridAPI.getChildGrids(); + expect(childGrids.length).toBe(1); + expect(childGrids[0].data.length).toBeGreaterThan(0); + + const row1 = hierarchicalGrid.gridAPI.get_row_by_index(2) as IgxHierarchicalRowComponent; + UIInteractions.simulateClickAndSelectEvent(row1.expander); + fixture.detectChanges(); + tick(); + + childGrids = hierarchicalGrid.gridAPI.getChildGrids(); + expect(childGrids.length).toBe(2); + expect(childGrids[0].data.length).toBeGreaterThan(0); + expect(childGrids[1].data.length).toBeGreaterThan(0); + })); }); describe('IgxHierarchicalGrid Template Changing Scenarios #hGrid', () => {