title: Rendering Angular components in Handsontable Cells
body: <p>In a project of mine, I try to display Angular Components (like an Autocomplete Dropdown Search) in a table. Because of the requirements I have (like multi-selecting different cells with <kbd>ctrl</kbd>+click) I decided to give it a go with handsontable.</p>
  <p>I've used the <a href="https://docs.handsontable.com/pro/1.18.0/demo-custom-renderers.html" rel="noreferrer">handsontable renderer</a> and <a href="https://medium.com/front-end-hacking/dynamically-add-components-to-the-dom-with-angular-71b0cb535286" rel="noreferrer">add the components dynamically</a>.</p>
  <p>The code looks like this</p>
  <p>matrix.component.ts</p>
  <pre class="lang-js prettyprint-override"><code>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) =&gt; {
          if (cellProperties.hasOwnProperty('ref')) {
            (cellProperties.ref as ComponentRef&lt;CellContainerComponent&gt;).instance.value = row;
          } else {
            cellProperties.ref = this.loadComponentAtDom(
              CellContainerComponent,
              td,
              ((component: any) =&gt; {
                component.template = this.button4Matrix;
                component.value = row;
              }));
          }
          return td;
        },
        readOnly: true,
      },
    ],
  });
  
  
  private loadComponentAtDom&lt;T&gt;(component: Type&lt;T&gt;, dom: Element, onInit?: (component: T) =&gt; void): ComponentRef&lt;T&gt; {
    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;
  }
  </code></pre>
  <p>What's my current issue is the lifecycle of the rendered angular components.</p>
  <p>Stuff I tried:</p>
  <ol>
  <li><strong>Do nothing</strong></li>
  </ol>
  <p><em>Tried Solution</em>: Doing nothing and leaving everything to Angular</p>
  <p><em>Problem</em>: Angular never calling the ngOnDestroy of the CellContainer.</p>
  <ol start="2">
  <li><strong>Saving componentRefs</strong></li>
  </ol>
  <p><em>Tried Solution</em>: Saving the componentRef in an Array and after a certain amount of rendering trying to destroy the components I
  rendered some time ago. Counting via time, handsontable hooks
  (verticalScroll/beforeRender/afterRender), in the render-method</p>
  <p><em>Problem</em>: Destroy of the angular component always throws an error ('cannot read property'nativeNode' of null') or the components get
  displayed completely wrong</p>
  <ol start="3">
  <li><strong>Check during rendering if an element is there</strong></li>
  </ol>
  <p><em>Tried Solution</em>: During the render: I checked if there's already a component and if it was I used to recycle the already-there component by adding a new value only.</p>
  <p><em>Problem</em>: The values get completely mixed up during scrolling.</p>
  <p>A link to my solution (and an implemented solution #3) is available on <a href="https://github.com/phhbr/handsontable-filled-with-ng-components" rel="noreferrer">github</a>.</p>
  <p>Does anyone have an idea of how to handle this in a clean way? If not the application gets slow &amp; unusable after a little bit of scrolling &amp; using the table.
  Better refer : <a href="https://handsontable.com/docs/8.2.0/tutorial-cell-function.html" rel="noreferrer">https://handsontable.com/docs/8.2.0/tutorial-cell-function.html</a></p>