Note that I am the author of Angular-Slickgrid
The answer was in the comment I left you in that issue and it doesn't look like you used it in your code which is why it doesn't work. Basically you are referencing older code of that issue (which I identified as not working, the answer was 1 of the last PR referenced on that same issue) the Example 3 comments has the all the answer and explanation you need (which is the code snippet I left before locking the issue and I locked it for that reason because that was the answer, I shorten the code snipped in the issue to make it clearer that it's what you need and for a quick recap it's the line below)
const allColumns = this.angularGrid.gridService.getAllColumnDefinitions();
it will not work with grid.getColumns()
simply because Angular-Slickgrid massages the column definitions (quick explanation is in the comments below) and it is mentioned in the Example 3 code here, you have to read the NOTE at the bottom which does cover your use case.
dynamicallyAddTitleHeader() {
const newCol = {
id: `title${this.duplicateTitleHeaderCount++}`,
name: 'Title',
field: 'title',
editor: {
model: Editors.text,
required: true,
validator: myCustomTitleValidator, // use a custom validator
},
sortable: true, minWidth: 100, filterable: true,
};
// you can dynamically add your column to your column definitions
// and then use the spread operator [...cols] OR slice to force Angular to review the changes
this.columnDefinitions.push(newCol);
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 "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.angularGrid.gridService.getAllColumnDefinitions();
allColumns.push(newCol);
this.columnDefinitions = [...allColumns]; // (or use slice) reassign to column definitions for Angular to do dirty checking
*/
}
So in your use case, if we zoom in to the commented NOTE that I wrote in that Example 3, that is exactly what you need to do because you are using the Checkbox Selector Extension (available in the Example 3 on this line).
dynamicallyAddTitleHeader() {
//... add your new column
// NOTE if you use an Extensions (Checkbox Selector, Row Detail, ...) that modifies the column definitions in any way
// 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.angularGrid.gridService.getAllColumnDefinitions();
allColumns.push(newCol);
this.columnDefinitions = [...allColumns]; // (or use slice) reassign to column definitions for Angular to do dirty checking
}
In case you want to know why is that? Then keep reading below for full explanation...
You might be wondering, why does Angular-Slickgrid massages the column definitions then? For a simple reason, SlickGrid internally uses editor
property (which is whichever editor you want to use like Editor.singleSelect
) but I wanted to align the Editors and the Filters with a similar structure, so for that reason you simply write a column definition like this (you can see below, both editor
and filter
are the same structure)
const genderList = [{ label: 'male', value: 'male' }, { label: 'male', value: 'male' }];
this.columnDefinitions = [
{
id: 'gender', name: 'Gender',
editors: {
model: Editors.singleSelect,
collection: genderList
},
filters: {
model: Editors.singleSelect
collection: genderList
}
}
];
but in reality after you initialize Angular-Slickgrid it becomes what is shown below, it does the following steps
- take the user column definition
editor
content and move it into a new property internalColumnEditor
- replace the
editor
property with the content of editor.model
this.columnDefinitions = [
{
id: 'gender', name: 'Gender',
editor: Editors.singleSelect,
internalColumnEditor: { // <-- this is used internally by Angular-Slickgrid you should never change this, you can read it though
model: Editors.singleSelect,
collection: genderList
},
filters: {
model: Editors.singleSelect
collection: genderList
}
}
];
and again this is simply to provide the same and easy to understand structure for both Editors & Filters. I could have used another approach and another property when I built it but I felt it was easier to use it this way.. and we rarely ever have to use the internalColumnEditor
, but there are some exceptions (like this SO question) and so it is good to understand the "why".