4

条件を設定するのではなくコードを改善しようとしているので、タイプ (文字列または templateRef) に応じてタブのタイトルを出力するのに役立つディレクティブまたは可能であればパイプを作成することにしました。私のコードは次のとおりです。 、このコードは私の Tabs/Tab コンポーネントだけでなく、Stepper/step コンポーネントでも使用されているため、再利用可能なものを作成できれば素晴らしいと思います。ElementRef、Renderer2、ViewContainerRef、TemplateRef で試してみましたが、うまくいきませんでした。

<ng-container *ngIf="tab.isLabelTemplate">
     <ng-container *ngTemplateOutlet="tab.title">
     </ng-container>
</ng-container>
<ng-container *ngIf="!tab.isLabelTemplate">{{ tab.title }}</ng-container>

isLabelTemplate は次のようになります。

get isLabelTemplate(): boolean {
  return this.title instanceof TemplateRef;
}

どうもありがとう :)

4

2 に答える 2

3

Angular の低レベル API を利用して、DOM の構造を動的に操作できます。

そのディレクティブがどのように見えるかの例を次に示します。

タイトル-template.directive.ts

import { Directive, TemplateRef, Renderer2, ViewContainerRef, Input } from '@angular/core';

@Directive({
  selector: '[titleTemplate]',
})
export class TitleTemplateDirective {
  @Input()
  set titleTemplate(value: string | TemplateRef<any>) {
    this.updateView(value);
  }

  textNode: Text;

  constructor(private vcRef: ViewContainerRef, private renderer: Renderer2) {}

  private updateView(value: string | TemplateRef<any>) {
    this.clear();

    if (!value) {
      return;
    }

    if (value instanceof TemplateRef) {
      this.vcRef.createEmbeddedView(value);
    } else {
      this.textNode = this.renderer.createText(value);
      const elem = this.vcRef.element.nativeElement;

      this.renderer.insertBefore(elem.parentNode, this.textNode, elem);
    }
  }

  private clear() {
    this.vcRef.clear();
    if (this.textNode) {
      this.renderer.removeChild(this.textNode.parentNode, this.textNode);
    }
  }

  ngOnDestroy() {
    this.clear();
  }
}

使用法:

<ng-container [titleTemplate]="title"></ng-container>  

分岐したスタックブリッツ

于 2020-01-08T20:01:31.927 に答える