From 903473d280b6d9f4992603c1b867a442a50ffa99 Mon Sep 17 00:00:00 2001 From: Ghislain Beaulac Date: Tue, 3 Mar 2020 10:22:31 -0500 Subject: [PATCH] fix(columns): remove columns dynamically with Editors, fixes #406 - when user has Editors and Row Selection, user must rebuild the facade (internalColumnEditor into editor) --- src/app/examples/grid-editor.component.ts | 22 ++++++++++---- .../examples/grid-localization.component.ts | 6 ++-- .../services/__tests__/grid.service.spec.ts | 29 ++++++++++++++++++- .../services/grid.service.ts | 18 +++++++++++- 4 files changed, 65 insertions(+), 10 deletions(-) diff --git a/src/app/examples/grid-editor.component.ts b/src/app/examples/grid-editor.component.ts index 6f7cf6a26..ddba34f0b 100644 --- a/src/app/examples/grid-editor.component.ts +++ b/src/app/examples/grid-editor.component.ts @@ -606,22 +606,34 @@ export class GridEditorComponent implements OnInit { this.columnDefinitions = this.columnDefinitions.slice(); // or use spread operator [...cols] // NOTE if you use an Extensions (Checkbox Selector, Row Detail, ...) that modifies the column definitions in any way - // you MUST use "getColumns()", using this will be ALL columns including the 1st column that is created internally + // you MUST use "getAllColumnDefinitions()" from the GridService, using this will be ALL columns including the 1st column that is created internally // for example if you use the Checkbox Selector (row selection), you MUST use the code below /* - const allColumns = this.gridObj.getColumns(); + const allColumns = this.angularGrid.gridService.getAllColumnDefinitions(); allColumns.push(newCol); this.columnDefinitions = [...allColumns]; // (or use slice) reassign to column definitions for Angular to do dirty checking */ } dynamicallyRemoveLastColumn() { - const allColumns = this.gridObj.getColumns(); + this.columnDefinitions.pop(); + this.columnDefinitions = this.columnDefinitions.slice(); + + // NOTE if you use an Extensions (Checkbox Selector, Row Detail, ...) that modifies the column definitions in any way + // you MUST use the code below, first you must reassign the Editor facade (from the internalColumnEditor back to the editor) + // in other words, SlickGrid is not using the same as Angular-Slickgrid uses (editor with a "model" and other properties are a facade, SlickGrid only uses what is inside the model) + /* + const allColumns = this.angularGrid.gridService.getAllColumnDefinitions(); + const allOriginalColumns = allColumns.map((column) => { + column.editor = column.internalColumnEditor; + return column; + }); // remove your column the full set of columns // and use slice or spread [...] to trigger an Angular dirty change - allColumns.pop(); - this.columnDefinitions = allColumns.slice(); + allOriginalColumns.pop(); + this.columnDefinitions = allOriginalColumns.slice(); + */ } setAutoEdit(isAutoEdit) { diff --git a/src/app/examples/grid-localization.component.ts b/src/app/examples/grid-localization.component.ts index 809a2fab9..cdb92d4a4 100644 --- a/src/app/examples/grid-localization.component.ts +++ b/src/app/examples/grid-localization.component.ts @@ -234,10 +234,10 @@ export class GridLocalizationComponent implements OnInit { this.columnDefinitions = this.columnDefinitions.slice(); // or use spread operator [...cols] // NOTE if you use an Extensions (Checkbox Selector, Row Detail, ...) that modifies the column definitions in any way - // you MUST use "getColumns()" instead to get ALL columns including the 1st column that is created internally - // for example if you use the Checkbox Selector (row selection), you need to use the code below + // you MUST use "getAllColumnDefinitions()" from the GridService, using this will be ALL columns including the 1st column that is created internally + // for example if you use the Checkbox Selector (row selection), you MUST use the code below /* - const allColumns = this.gridObj.getColumns(); + const allColumns = this.angularGrid.gridService.getAllColumnDefinitions(); allColumns.push(newCol); this.columnDefinitions = [...allColumns]; // (or use slice) reassign to column definitions for Angular to do dirty checking */ diff --git a/src/app/modules/angular-slickgrid/services/__tests__/grid.service.spec.ts b/src/app/modules/angular-slickgrid/services/__tests__/grid.service.spec.ts index e5c576242..14bad63f7 100644 --- a/src/app/modules/angular-slickgrid/services/__tests__/grid.service.spec.ts +++ b/src/app/modules/angular-slickgrid/services/__tests__/grid.service.spec.ts @@ -1,6 +1,6 @@ import { TestBed } from '@angular/core/testing'; import { TranslateService, TranslateModule } from '@ngx-translate/core'; -import { GridService, ExtensionService, FilterService, GridStateService, SortService } from '..'; +import { GridService, ExtensionService, FilterService, GridStateService, SortService, SharedService } from '..'; import { CellArgs, Column, OnEventArgs, GridOption } from './../../models'; declare var Slick: any; @@ -62,6 +62,7 @@ const gridStub = { describe('Grid Service', () => { let service: GridService; + let sharedService = new SharedService(); let translate: TranslateService; jest.spyOn(gridStub, 'getOptions').mockReturnValue({ enableAutoResize: true } as GridOption); @@ -71,12 +72,14 @@ describe('Grid Service', () => { { provide: ExtensionService, useValue: extensionServiceStub }, { provide: FilterService, useValue: filterServiceStub }, { provide: GridStateService, useValue: gridStateServiceStub }, + { provide: SharedService, useValue: sharedService }, { provide: SortService, useValue: sortServiceStub }, GridService, ], imports: [TranslateModule.forRoot()] }); translate = TestBed.get(TranslateService); + sharedService = TestBed.get(SharedService); service = TestBed.get(GridService); service.init(gridStub, dataviewStub); }); @@ -89,6 +92,30 @@ describe('Grid Service', () => { expect(service).toBeTruthy(); }); + describe('getAllColumnDefinitions method', () => { + it('should call "allColumns" GETTER ', () => { + const mockColumns = [{ id: 'field1', field: 'field1', width: 100 }, { id: 'field2', field: 'field2', width: 100 }]; + const getSpy = jest.spyOn(SharedService.prototype, 'allColumns', 'get').mockReturnValue(mockColumns); + + const output = service.getAllColumnDefinitions(); + + expect(getSpy).toHaveBeenCalled(); + expect(output).toEqual(mockColumns); + }); + }); + + describe('getVisibleColumnDefinitions method', () => { + it('should call "visibleColumns" GETTER ', () => { + const mockColumns = [{ id: 'field1', field: 'field1', width: 100 }, { id: 'field2', field: 'field2', width: 100 }]; + const getSpy = jest.spyOn(SharedService.prototype, 'visibleColumns', 'get').mockReturnValue(mockColumns); + + const output = service.getVisibleColumnDefinitions(); + + expect(getSpy).toHaveBeenCalled(); + expect(output).toEqual(mockColumns); + }); + }); + describe('upsertItem methods', () => { afterEach(() => { jest.clearAllMocks(); diff --git a/src/app/modules/angular-slickgrid/services/grid.service.ts b/src/app/modules/angular-slickgrid/services/grid.service.ts index 0e73371d5..a5bd67dda 100644 --- a/src/app/modules/angular-slickgrid/services/grid.service.ts +++ b/src/app/modules/angular-slickgrid/services/grid.service.ts @@ -1,4 +1,6 @@ import { Injectable } from '@angular/core'; +import { Subject } from 'rxjs'; + import { CellArgs, Column, @@ -11,8 +13,8 @@ import { import { ExtensionService } from './extension.service'; import { FilterService } from './filter.service'; import { GridStateService } from './gridState.service'; +import { SharedService } from './shared.service'; import { SortService } from './sort.service'; -import { Subject } from 'rxjs'; // using external non-typed js libraries declare var Slick: any; @@ -34,6 +36,7 @@ export class GridService { private extensionService: ExtensionService, private filterService: FilterService, private gridStateService: GridStateService, + private sharedService: SharedService, private sortService: SortService ) { } @@ -58,6 +61,19 @@ export class GridService { } } + /** + * Get all column set in the grid, that is all visible/hidden columns + * and also include any extra columns used by some plugins (like Row Selection, Row Detail, ...) + */ + getAllColumnDefinitions() { + return this.sharedService.allColumns; + } + + /** Get only visible column definitions and also include any extra columns by some plugins (like Row Selection, Row Detail, ...) */ + getVisibleColumnDefinitions() { + return this.sharedService.visibleColumns; + } + /** * From a SlickGrid Event triggered get the Column Definition and Item Data Context *