在我的一个项目中,我尝试在表格中显示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

问题:Angular从不调用CellContainer的ngOnDestroy函数。

储蓄componentRefs

尝试的解决方案:将componentRef保存在一个数组中,并在一定数量的渲染后试图销毁组件I 一段时间前渲染。通过时间计数,手握钩子 (verticalScroll/beforeRender/afterRender),在渲染方法中

问题:angular组件的销毁总是抛出一个错误('不能读取null'的属性' nativenode ')或组件get 显示完全错误

在呈现过程中检查是否有元素存在

尝试的解决方案:在渲染期间:我检查是否已经有一个组件,如果它是我用来回收已经存在的组件,只添加一个新值。

问题:在滚动过程中,值会完全混淆。

我的解决方案(和一个实现的解决方案#3)的链接在github上可用。

有人知道怎么干净利落地处理这件事吗?如果不是,应用程序变得缓慢和不可用后,一点点滚动和使用表格。 更好的参考:https://handsontable.com/docs/8.2.0/tutorial-cell-function.html


可能您需要尝试如下所示的changeDetection,强制对组件进行新的更改。

changeDetection: ChangeDetectionStrategy.OnPush

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

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

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

});