Hur man anropar en komponent med samma som strängen "component name" i HTML med Angular 7


Jag försöker anropa komponenter med strängnycklar i Angular 7. Eftersom min tjänst ger mig nycklar som komponenter filtrerar för att visa på sidan per användare. Kan jag göra denna filtrering speciellt i HTML?

<pg-tab *ngFor="let tab of tabs; let index = index">
  <ng-template #TabHeading>
    {{tab.headerText}}
  <a (click)="removeTab(index)" style="padding: 5px;"><i class="fa fa-times fa-lg" style="color:orangered;"></i></a>
  </ng-template>
  <div class="row column-seperation" *ngIf="tab.componentName === 'grid-sample'">
    <app-grid-sample></app-grid-sample>
  </div>

  <div class="row column-seperation" *ngIf="tab.componentName === 'pdf-export-sample'">
    <app-pdf-export-sample></app-pdf-export-sample>
  </div>
  <div class="row column-seperation" *ngIf="tab.componentName === 'notify-sample'">
    <app-notify-sample></app-notify-sample>
  </div>
  <div class="row column-seperation" *ngIf="tab.componentName === 'loader-sample'">
    <app-loader-sample></app-loader-sample>
  </div>
  <div class="row column-seperation" *ngIf="tab.componentName === 'tt-form-elements'">
    <app-tt-form-elements></app-tt-form-elements>
  </div>
  <div class="row column-seperation" *ngIf="tab.componentName === 'tt-layouts'">
    <app-tt-layouts></app-tt-layouts>
  </div>
</pg-tab>

Jag sökte om attributet innerHtml men det fungerar inte för Angular-komponenter som i det exemplet.

html

<div [innerHTML]="pageDetail"></div>

typescript

private _pageDetail: string = '<app-tab-page1 [tab]="tab" [tabsLength]="tabs.length" [tabs]="tabs"></app-tab-page1><button>Naber</button>';

public get pageDetail(): SafeHtml {
  return this._sanitizer.bypassSecurityTrustHtml(this._pageDetail);
}

Du kan gissa att det inte ser bra ut just nu. Om det är möjligt vill jag göra det kortare och rensa de "*ngIf"-attributen i html.

Har du några idéer om det?

Något liknande detta

<div class="row column-seperation" tab.componentName>
  <app-tab.componentName></app-tab.componentName>
</div>

Obs: Förlåt för mina grammatikfel.

Svar #1

Du kan skapa en dynamisk komponent med namn på detta sätt:

Flikobjekt är en direktiv:

@ViewChildren('tabItem', {read: ViewContainerRef} ) tabItem:  QueryList<ViewContainerRef>;

Här skapa dynamisk komponent:

    const factories = Array.from(this.componentFactoryResolver['_factories'].keys());
    const factoryClass = <Type<any>>factories.find((x: any) => x.name === dynamicComponentName);
    if (factoryClass !== undefined) {
      const factory = this.componentFactoryResolver.resolveComponentFactory(factoryClass);
      const ref = this.tabItem.viewContainerRef;
      ref.createComponent(factory);
    }

Du kan också titta på Angular-dokumentationen: dynamisk komponent

Svar #2

Du skulle enkelt kunna använda ngSwitch vilket gör det kortare, men dynamiskt komponentnamn är, så vitt jag vet, inte möjligt.

<div class="row column-seperation" *ngSwitch="tab.componentName">
    <app-grid-sample *ngSwitchCase="'grid-sample'"></app-grid-sample>
    <app-pdf-export-sample *ngSwitchCase="'pdf-export-sample''"></app-pdf-export-sample>
     //etc ...
  </div>