如何在 angular slickgrid 自定义格式化程序中显示自定义 angular 标签

How to display custom angular tag in angular slickgrid custom formatter

在 angular slickgrid 中,我使用自定义 angular 组件来显示用户信息。可以使用自定义格式化程序显示自定义 angular 标签。在这里我分享了我的代码片段。

export const CspfmAuditInfoFormatter: Formatter = (row: number, cell: number, value: any, columnDef: any, dataContext: any, grid: any) => {
  return `<ion-buttons>
        <cspfm-audit-info [setIcon]="ios-information-circle-outline" [setIconClass]="" [setInfo]="${dataContext}"></cspfm-audit-info>
    </ion-buttons>`
}; 

cspfm-audit-info是我自己的angular显示数据审计信息的组件。我想显示 cspfm-audit-info。


软件版本

Angular : 7.3.5

Angular-Slickgrid:2.19.0

打字稿:3.1.6

操作系统:Windows10

节点:10.16.3

NPM:6.9.0

在 Angular-Slickgrid 中被多次询问,查看这些问题 #7 and #148 and this other Stack Overflow Question How to render custom angular component instantly in angular slickgrid

简短的回答是不,您不能使用自定义格式化程序来做到这一点,但您可以使用 asyncPostRenderer 来做到这一点,这里是 Wiki - Using Angular Component with asyncPostRenderer and here's the Example 22 示例。

但是使用 asyncPostRenderer 有很多缺点,我在 Wiki 中写了它们,这里是主要部分:

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.

那我就这样结束了

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.

如果你真的想试一试(我几乎可以肯定你会在尝试后改变主意),这是代码

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));
    }
  }
}

结论

最后一句话,它很慢,我从来没有亲自使用过,但是嘿,如果你想要一个缓慢的渲染是可行的......我的用户当然不想要这样,所以我从不使用它们。