Skip to content

Commit 679d086

Browse files
committed
fix(grid): update children when add or remove column in column group #5837
1 parent 14e1e2e commit 679d086

File tree

2 files changed

+74
-41
lines changed

2 files changed

+74
-41
lines changed

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

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ import {
5757
selector: 'igx-column',
5858
template: ``
5959
})
60-
export class IgxColumnComponent implements AfterContentInit {
60+
export class IgxColumnComponent implements AfterContentInit, OnDestroy {
6161
/**
6262
* Sets/gets the `field` value.
6363
* ```typescript
@@ -838,13 +838,13 @@ export class IgxColumnComponent implements AfterContentInit {
838838
return false;
839839
}
840840

841-
/**
842-
* Returns a boolean indicating if the column is a child of a `ColumnLayout` for multi-row layout.
843-
* ```typescript
844-
* let columnLayoutChild = this.column.columnLayoutChild;
845-
* ```
846-
* @memberof IgxColumnComponent
847-
*/
841+
/**
842+
* Returns a boolean indicating if the column is a child of a `ColumnLayout` for multi-row layout.
843+
* ```typescript
844+
* let columnLayoutChild = this.column.columnLayoutChild;
845+
* ```
846+
* @memberof IgxColumnComponent
847+
*/
848848
get columnLayoutChild() {
849849
return this.parent && this.parent.columnLayout;
850850
}
@@ -979,6 +979,11 @@ export class IgxColumnComponent implements AfterContentInit {
979979
* @memberof IgxColumnComponent
980980
*/
981981
children: QueryList<IgxColumnComponent>;
982+
/**
983+
* @hidden
984+
*/
985+
protected destroy$ = new Subject<boolean>();
986+
982987
/**
983988
*@hidden
984989
*/
@@ -1162,7 +1167,7 @@ export class IgxColumnComponent implements AfterContentInit {
11621167
if (!col.colStart) {
11631168
return;
11641169
}
1165-
const newWidthSet = col.widthSetByUser && columnSizes[col.colStart - 1] && !columnSizes[col.colStart - 1].widthSetByUser;
1170+
const newWidthSet = col.widthSetByUser && columnSizes[col.colStart - 1] && !columnSizes[col.colStart - 1].widthSetByUser;
11661171
const newSpanSmaller = columnSizes[col.colStart - 1] && columnSizes[col.colStart - 1].colSpan > col.gridColumnSpan;
11671172
const bothWidthsSet = col.widthSetByUser && columnSizes[col.colStart - 1] && columnSizes[col.colStart - 1].widthSetByUser;
11681173
const bothWidthsNotSet = !col.widthSetByUser && columnSizes[col.colStart - 1] && !columnSizes[col.colStart - 1].widthSetByUser;
@@ -1234,8 +1239,8 @@ export class IgxColumnComponent implements AfterContentInit {
12341239
for (; j < columnSizes[i].colSpan && i + j + 1 < columnSizes[i].colEnd; j++) {
12351240
if (columnSizes[i + j] &&
12361241
((!columnSizes[i].width && columnSizes[i + j].width) ||
1237-
(!columnSizes[i].width && !columnSizes[i + j].width && columnSizes[i + j].colSpan <= columnSizes[i].colSpan) ||
1238-
(!!columnSizes[i + j].width && columnSizes[i + j].colSpan <= columnSizes[i].colSpan))) {
1242+
(!columnSizes[i].width && !columnSizes[i + j].width && columnSizes[i + j].colSpan <= columnSizes[i].colSpan) ||
1243+
(!!columnSizes[i + j].width && columnSizes[i + j].colSpan <= columnSizes[i].colSpan))) {
12391244
// If we reach an already defined column that has width and the current doesn't have or
12401245
// if the reached column has bigger colSpan we stop.
12411246
break;
@@ -1283,8 +1288,8 @@ export class IgxColumnComponent implements AfterContentInit {
12831288
}
12841289

12851290
protected getColumnSizesString(children: QueryList<IgxColumnComponent>): string {
1286-
const res = this.getFilledChildColumnSizes(children);
1287-
return res.join(' ');
1291+
const res = this.getFilledChildColumnSizes(children);
1292+
return res.join(' ');
12881293
}
12891294

12901295
public getResizableColUnderEnd(): MRLResizeColumnInfo[] {
@@ -1298,7 +1303,7 @@ export class IgxColumnComponent implements AfterContentInit {
12981303

12991304
for (let i = 0; i < columnSized.length; i++) {
13001305
if (this.colStart <= i + 1 && i + 1 < colEnd) {
1301-
targets.push({ target: columnSized[i].ref, spanUsed: 1});
1306+
targets.push({ target: columnSized[i].ref, spanUsed: 1 });
13021307
}
13031308
}
13041309

@@ -1377,7 +1382,7 @@ export class IgxColumnComponent implements AfterContentInit {
13771382
grid.resetCaches();
13781383
grid.notifyChanges();
13791384
if (this.columnLayoutChild) {
1380-
this.grid.columns.filter(x => x.columnLayout).forEach( x => x.populateVisibleIndexes());
1385+
this.grid.columns.filter(x => x.columnLayout).forEach(x => x.populateVisibleIndexes());
13811386
}
13821387
this.grid.filteringService.refreshExpressions();
13831388
// this.grid.refreshSearch(true);
@@ -1440,7 +1445,7 @@ export class IgxColumnComponent implements AfterContentInit {
14401445

14411446
grid.notifyChanges();
14421447
if (this.columnLayoutChild) {
1443-
this.grid.columns.filter(x => x.columnLayout).forEach( x => x.populateVisibleIndexes());
1448+
this.grid.columns.filter(x => x.columnLayout).forEach(x => x.populateVisibleIndexes());
14441449
}
14451450
this.grid.filteringService.refreshExpressions();
14461451
// this.grid.refreshSearch(true);
@@ -1640,6 +1645,14 @@ export class IgxColumnComponent implements AfterContentInit {
16401645
* @hidden
16411646
*/
16421647
public populateVisibleIndexes() { }
1648+
1649+
/**
1650+
* @hidden
1651+
*/
1652+
public ngOnDestroy() {
1653+
this.destroy$.next(true);
1654+
this.destroy$.complete();
1655+
}
16431656
}
16441657

16451658

@@ -1650,8 +1663,6 @@ export class IgxColumnComponent implements AfterContentInit {
16501663
template: ``
16511664
})
16521665
export class IgxColumnGroupComponent extends IgxColumnComponent implements AfterContentInit, OnDestroy {
1653-
private destroy$ = new Subject<boolean>();
1654-
16551666
@ContentChildren(IgxColumnComponent, { read: IgxColumnComponent })
16561667
children = new QueryList<IgxColumnComponent>();
16571668
/**
@@ -1778,20 +1789,17 @@ export class IgxColumnGroupComponent extends IgxColumnComponent implements After
17781789
if (this.headTemplate && this.headTemplate.length) {
17791790
this._headerTemplate = this.headTemplate.toArray()[0].template;
17801791
}
1781-
this.updateChildren();
1782-
this.children.changes.pipe(takeUntil(this.destroy$))
1783-
.subscribe(() => {
1784-
this.updateChildren();
1792+
this.children.reset(this.children.toArray().slice(1));
1793+
this.children.forEach(child => {
1794+
child.parent = this;
17851795
});
1786-
}
1787-
1788-
protected updateChildren() {
1789-
if (this.children && this.children.toArray().length > 0 && this.children.toArray()[0] === this) {
1796+
this.children.changes.pipe(takeUntil(this.destroy$))
1797+
.subscribe(() => {
17901798
this.children.reset(this.children.toArray().slice(1));
17911799
this.children.forEach(child => {
17921800
child.parent = this;
17931801
});
1794-
}
1802+
});
17951803
}
17961804

17971805
/**
@@ -1838,7 +1846,7 @@ export class IgxColumnGroupComponent extends IgxColumnComponent implements After
18381846
return acc;
18391847
}
18401848
if (typeof val.width === 'string' && val.width.indexOf('%') !== -1) {
1841-
isChildrenWidthInPercent = true;
1849+
isChildrenWidthInPercent = true;
18421850
}
18431851
return acc + parseInt(val.width, 10);
18441852
}, 0)}`;
@@ -1851,14 +1859,6 @@ export class IgxColumnGroupComponent extends IgxColumnComponent implements After
18511859
// D.P. constructor duplication due to es6 compilation, might be obsolete in the future
18521860
super(gridAPI, cdr);
18531861
}
1854-
1855-
/**
1856-
* @hidden
1857-
*/
1858-
public ngOnDestroy() {
1859-
this.destroy$.next(true);
1860-
this.destroy$.complete();
1861-
}
18621862
}
18631863

18641864
@Component({
@@ -1867,7 +1867,7 @@ export class IgxColumnGroupComponent extends IgxColumnComponent implements After
18671867
selector: 'igx-column-layout',
18681868
template: ``
18691869
})
1870-
export class IgxColumnLayoutComponent extends IgxColumnGroupComponent implements AfterContentInit {
1870+
export class IgxColumnLayoutComponent extends IgxColumnGroupComponent implements AfterContentInit, OnDestroy {
18711871
public childrenVisibleIndexes = [];
18721872
/**
18731873
* Gets the width of the column layout.
@@ -1952,7 +1952,7 @@ export class IgxColumnLayoutComponent extends IgxColumnGroupComponent implements
19521952
this.children.forEach(child => child.hidden = value);
19531953
if (this.grid && this.grid.columns && this.grid.columns.length > 0) {
19541954
// reset indexes in case columns are hidden/shown runtime
1955-
this.grid.columns.filter(x => x.columnGroup).forEach( x => x.populateVisibleIndexes());
1955+
this.grid.columns.filter(x => x.columnGroup).forEach(x => x.populateVisibleIndexes());
19561956
}
19571957
}
19581958

@@ -1991,16 +1991,16 @@ export class IgxColumnLayoutComponent extends IgxColumnGroupComponent implements
19911991
const grid = this.gridAPI.grid;
19921992
const columns = grid && grid.pinnedColumns && grid.unpinnedColumns ? grid.pinnedColumns.concat(grid.unpinnedColumns) : [];
19931993
const orderedCols = columns
1994-
.filter(x => !x.columnGroup && !x.hidden)
1995-
.sort((a, b) => a.rowStart - b.rowStart || columns.indexOf(a.parent) - columns.indexOf(b.parent) || a.colStart - b.colStart);
1994+
.filter(x => !x.columnGroup && !x.hidden)
1995+
.sort((a, b) => a.rowStart - b.rowStart || columns.indexOf(a.parent) - columns.indexOf(b.parent) || a.colStart - b.colStart);
19961996
this.children.forEach(child => {
19971997
const rs = child.rowStart || 1;
19981998
let vIndex = 0;
19991999
// filter out all cols with larger rowStart
20002000
const cols = orderedCols.filter(c =>
20012001
!c.columnGroup && (c.rowStart || 1) <= rs);
20022002
vIndex = cols.indexOf(child);
2003-
this.childrenVisibleIndexes.push({column: child, index: vIndex});
2003+
this.childrenVisibleIndexes.push({ column: child, index: vIndex });
20042004
});
20052005
}
20062006
}

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1553,6 +1553,39 @@ describe('IgxGrid - multi-column headers #grid', () => {
15531553
expect(firstColumnGroup.header).toEqual(expectedColumnName);
15541554
expect(expectedColumnListLength).toEqual(columnLength);
15551555
});
1556+
1557+
it('There shouldn\'t be any errors when dynamically removing or adding a column in column group', () => {
1558+
const fixture = TestBed.createComponent(DynamicColGroupsGridComponent);
1559+
fixture.detectChanges();
1560+
1561+
const grid = fixture.componentInstance.grid;
1562+
1563+
expect(grid.columnList.length).toEqual(10);
1564+
1565+
expect(() => {
1566+
// Delete column
1567+
fixture.componentInstance.columnGroups[0].columns.splice(0, 1);
1568+
fixture.detectChanges();
1569+
}).not.toThrow();
1570+
1571+
expect(grid.columnList.length).toEqual(9);
1572+
1573+
expect(() => {
1574+
// Add column
1575+
fixture.componentInstance.columnGroups[0].columns.push({ field: 'Fax', type: 'string' });
1576+
fixture.detectChanges();
1577+
}).not.toThrow();
1578+
1579+
expect(grid.columnList.length).toEqual(10);
1580+
1581+
expect(() => {
1582+
// Update column
1583+
fixture.componentInstance.columnGroups[0].columns[1] = { field: 'City', type: 'string' };
1584+
fixture.detectChanges();
1585+
}).not.toThrow();
1586+
1587+
expect(grid.columnList.length).toEqual(10);
1588+
});
15561589
});
15571590

15581591
@Component({

0 commit comments

Comments
 (0)