这在 Angular-Slickgrid 中被多次询问,请参阅这些问题#7和#148以及其他堆栈溢出问题如何在 angular slickgrid 中立即呈现自定义角度组件
简短的回答是“不”,您不能使用自定义格式化程序来执行此操作,但您可以使用asyncPostRenderer
此处的Wiki - Using Angular Component with asyncPostRenderer来执行此操作,这是带有示例的示例 22。
但是使用asyncPostRenderer
有很多缺点,我在 Wiki 中写了它们,这是主要部分:
首先...为什么我们不能将 Angular 组件与客户格式化程序一起使用?由于 Angular 是如何构建的,它需要一个完整的循环来使用数据渲染组件,但是 SlickGrid Formatter 只需要字符串输出并且它必须立即(同步)并且 Angular 组件只能以异步方式返回(您可以立即返回,但不会填充数据)。这就是它不能使用 Formatter 的原因,但是 SlickGrid 提供了类似于 Formatter 并且以异步方式工作的 asyncPostRender。这样可以,但它有一些缺点,因为它是异步的,所以渲染速度稍慢(您可能会直观地看到它在屏幕上渲染)。尽管如此,使用 jQuery 和/或 HTML 的常规格式化程序仍然是首选方式(至少对我而言)......但是,嘿,
然后我完成这个
更好的解决方案是尽可能多地使用自定义格式化程序,因为使用 Angular 组件的速度asyncPostRender
很慢(警告您)。它们很慢,因为它们需要一个完整的周期,不能被缓存并且在每行渲染后渲染(因为它们的异步性质),而自定义格式化程序与行本身同时渲染,因为它们本质上是同步的。
如果您真的想尝试一下(我几乎可以肯定您在尝试后会改变主意),这里是代码
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));
}
}
}
结论
最后一句话,它很慢,我从来没有亲自使用过,但是如果你希望渲染速度很慢,这是可行的……我的用户当然不希望这样,所以我从不使用它们。