0

在 angular slickgrid 中,我使用自定义 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是我自己的角度组件,用于显示数据审计信息。我想显示 cspfm-audit-info。


软件版本

角度:7.3.5

Angular-Slickgrid:2.19.0

打字稿:3.1.6

操作系统:Windows 10

节点:10.16.3

NPM:6.9.0

4

1 回答 1

1

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

结论

最后一句话,它很慢,我从来没有亲自使用过,但是如果你希望渲染速度很慢,这是可行的……我的用户当然不希望这样,所以我从不使用它们。

于 2020-07-21T22:33:24.063 回答