在Handsontable单元格中呈现Angular组件

241
在我的一个项目中,我尝试在表格中显示Angular组件(例如自动完成下拉搜索)。由于我的要求(例如使用ctrl+单击多选不同的单元格),我决定使用handsontable。我使用了handsontable渲染器动态添加组件。代码如下:

matrix.component.ts

this.hot = new Handsontable(this.handsontable.nativeElement, {
  data: this.tableData,
  colWidths: [80, 300],
  colHeaders: ['Id', 'Custom Component'],
  columns: [
    {
      data: 'id',
    },
    {
      data: 'id',
      renderer: (instance: any, td: any, row: any, col: any, prop: any, value: any, cellProperties: any) => {
        if (cellProperties.hasOwnProperty('ref')) {
          (cellProperties.ref as ComponentRef<CellContainerComponent>).instance.value = row;
        } else {
          cellProperties.ref = this.loadComponentAtDom(
            CellContainerComponent,
            td,
            ((component: any) => {
              component.template = this.button4Matrix;
              component.value = row;
            }));
        }
        return td;
      },
      readOnly: true,
    },
  ],
});


private loadComponentAtDom<T>(component: Type<T>, dom: Element, onInit?: (component: T) => void): ComponentRef<T> {
  let componentRef;
  try {
    const componentFactory = this.componentFactoryResolver.resolveComponentFactory(component);
    componentRef = componentFactory.create(this.injector, [], dom);
    onInit ? onInit(componentRef.instance) : console.log('no init');
    this.appRef.attachView(componentRef.hostView);
  } catch (e) {
    console.error('Unable to load component', component, 'at', dom);
    throw e;
  }
  return componentRef;
}

我的当前问题是已渲染的Angular组件的生命周期。
我尝试过的方法:
1. 什么都不做:尝试解决方案:什么都不做,让一切交给Angular处理。问题:Angular从未调用CellContainer的ngOnDestroy。
2. 保存componentRefs:尝试解决方案:将componentRef保存在数组中,在渲染一定数量后尝试销毁之前渲染的组件。通过时间计数,handsontable hooks(verticalScroll/beforeRender/afterRender),在render方法中进行计数。问题:销毁Angular组件总是会抛出错误(“无法读取null的nativeNode属性”),或者组件的显示完全错误。
3. 在渲染期间检查元素是否存在:尝试解决方案:在渲染期间:检查是否已经有组件,如果有,则通过添加新值来回收已经存在的组件。问题:值在滚动期间完全混乱。
我的解决方案链接(以及已实现的解决方案#3)可在github找到。

有没有想过以一种干净的方式来处理这个问题?否则,应用程序在滚动和使用表格后会变得缓慢且无法使用。 更好的参考:https://handsontable.com/docs/8.2.0/tutorial-cell-function.html


30
我决定使用ag-grid社区版,而不是handsontable。在那里,渲染单元的生命周期非常容易管理。我也看了ngx-datatable,但它目前不支持固定列,这是该项目的要求之一。 - phhbr
3
这个答案有帮助吗?https://dev59.com/bVcP5IYBdhLWcg3wDWRq#44942210 - Alex Pappas
3
我尝试集成时遇到了CSS问题,通过在我的公共CSS文件中引入此代码解决了该问题。 - Er Abdul Meman
3
你能修复仓库的链接吗? - user981225
嗯,Handsontable有Angular集成 https://www.npmjs.com/package/@handsontable/angular 你试过使用它吗? - Xesenix
2个回答

1

使用单元格渲染器。 在配置列时,使用您选择的渲染器名称:

const container = document.getElementById('container');

const hot = new Handsontable(container,
 {
  data: someData,
  columns: 
[{
    renderer: 'numeric'
  }]

});

-5
也许你需要尝试以下的changeDetection,强制将新的更改应用到你的组件中。
changeDetection: ChangeDetectionStrategy.OnPush

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接