That was asked multiple times in Angular-Slickgrid, see these issues #7 and #148 and this other Stack Overflow Question How to render custom angular component instantly in angular slickgrid
The short answer is NO you cannot do that with a Custom Formatter, but you can do it with asyncPostRenderer
and here's the Wiki - Using Angular Component with asyncPostRenderer and here's the Example 22 with a sample.
BUT using asyncPostRenderer
has lots of disadvantage and I wrote them in the Wiki, here's the main part:
First of... Why can't we use Angular Component with Customer Formatters? Because of how Angular is built, it requires a full cycle for the component to be rendered with data, however SlickGrid Formatter requires only string output and it must be right away (synchronous) and Angular Component can only be returned in an async fashion (you could return it right away but the data won't be populated). That is the reason that it's not doable with a Formatter, however SlickGrid offers asyncPostRender which is similar to a Formatter and works in an async fashion. So that works, but it has some drawback, since it's async, it is slightly slower to render (you might visually see it rendering on the screen). All that to say, regular Formatters with jQuery and/or HTML is still the preferred way (at least to me)... but hey, if you really wish to use Angular Component, well then it's possible, just remember it's async though and slightly slower to render.
Then I finish with this
A Better Solution is to use Custom Formatters as much as possible because using an Angular Components with asyncPostRender
are SLOW (you are warned). They are slow because they require a full cycle, cannot be cached and are rendered after each rows are rendered (because of their asynchronous nature), while Custom Formatters are rendered at the same time as the row itself since they are synchronous in nature.
If you really wish to give it a try (I'm nearly sure that you'll change your mind after trying it), here's the code
import {
AngularGridInstance,
AngularUtilService,
} from 'angular-slickgrid';
export class MyComponent {
constructor(private angularUtilService: AngularUtilService){ }
initGrid() {
this.columnDefinitions = [
{
id: 'assignee2',
name: 'Assignee with Angular Component',
field: 'assignee',
minWidth: 100,
filterable: true,
sortable: true,
filter: {
model: new CustomAngularComponentFilter(), // create a new instance to make each Filter independent from each other
collection: this.assignees,
params: {
component: FilterNgSelectComponent,
}
},
queryFieldFilter: 'assignee.id', // for a complex object it's important to tell the Filter which field to query and our CustomAngularComponentFilter returns the "id" property
queryFieldSorter: 'assignee.name',
// loading formatter, text to display while Post Render gets processed
formatter: () => '...',
// to load an Angular Component, you cannot use a Formatter since Angular needs at least 1 cycle to render everything
// you can use a PostRenderer but you will visually see the data appearing,
// which is why it's still better to use regular Formatter (with jQuery if need be) instead of Angular Component
asyncPostRender: this.renderAngularComponent.bind(this),
params: {
component: CustomTitleFormatterComponent,
angularUtilService: this.angularUtilService,
complexFieldLabel: 'assignee.name' // for the exportCustomFormatter
},
exportCustomFormatter: Formatters.complexObject,
}
];
this.gridOptions = {
enableAsyncPostRender: true, // for the Angular PostRenderer, don't forget to enable it
asyncPostRenderDelay: 0, // also make sure to remove any delay to render it
};
}
renderAngularComponent(cellNode: HTMLElement, row: number, dataContext: any, colDef: Column) {
if (colDef.params.component) {
const componentOutput = this.angularUtilService.createAngularComponent(colDef.params.component);
Object.assign(componentOutput.componentRef.instance, { item: dataContext });
// use a delay to make sure Angular ran at least a full cycle and make sure it finished rendering the Component
setTimeout(() => $(cellNode).empty().html(componentOutput.domElement));
}
}
}
Conclusion
Final Word, it's slow and I never personally use, but hey it's doable if you wish to have a slow rendering... my users certainly don't want that and so I never use them.