#104393
dilbert
Participant

Here is an example that illustrates the issue. The first 2 tabs get a dynamic component, but those that are added later do not.

Template:

<div>Num of smart-tab-items: {{smartItems.length}}</div>
<div>Num of tabs: {{numTabs}}</div>
<smart-tabs #tabs id="tabs" class="demoTabsShort" [closeButtons]="true" [closeButtonMode]="'selected'"
[addNewTab]="true" (addNewTabClick)="onAddNewTabClick($event)" [reorder]="true">
    <smart-tab-item [label]="'Tab_1'"><ng-container app-view-ref></ng-container></smart-tab-item>
    <smart-tab-item [label]="'Tab_2'"><ng-container app-view-ref></ng-container></smart-tab-item>
</smart-tabs>

Main component:

import { Component, AfterViewInit, ViewChildren, QueryList, ViewChild } from '@angular/core';
import { TabItemComponent, TabsComponent } from 'smart-webcomponents-angular/tabs';
import { ThingComponent } from './thing.component';
import { ViewRefAnchorDirective } from './view-ref-anchor.directive';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {

  // I am expecting this list to be updated when new tabs are added.
  @ViewChildren(TabItemComponent) smartItems = new QueryList();

  @ViewChildren(ViewRefAnchorDirective) anchors = new QueryList();

  @ViewChild('tabs', {read: TabsComponent, static: false}) tabs!: TabsComponent;

  numTabs = 0;

  ngAfterViewInit(): void {
    this.tabs.getTabs().then(tabs => {
      this.numTabs = tabs.length;
    });

    this.anchors.forEach(tab => this.loadComponent(tab));
  }

  onAddNewTabClick(event: Event) {
    this.tabs.getTabs().then(tabs => {
      this.numTabs = tabs.length;

      // At this point this.smartItems only has the original 2 smart-tab-items
      // It would appear the new tabs are not known to Angular since they aren't
      // added to the QueryList.

      // this.anchors also only has the original 2.  this.anchors.last references
      // the second tab.  Additional tabs do not get a new component.
      this.loadComponent(this.anchors.last);
    });
  }

  loadComponent(viewRefAnchor: ViewRefAnchorDirective) {
    viewRefAnchor.viewContainerRef.clear();
    viewRefAnchor.viewContainerRef.createComponent(ThingComponent);
  }
}

Anchor directive:

import { Directive, ViewContainerRef } from "@angular/core";
/**
 * An directive to expose the ViewContainerRef to allow components to be dynamically
 * created and added.
 */
@Directive({
  selector: '[app-view-ref]'
})
export class ViewRefAnchorDirective {

  constructor(public viewContainerRef: ViewContainerRef) { }

}

Dynamic component:

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-thing',
  template: '<p>test-component works!</p>'
})
export class ThingComponent implements OnInit {

  constructor() { }

  ngOnInit(): void {
  }

}