代码之家  ›  专栏  ›  技术社区  ›  PVG

Angular 16+使用ngTemplateOutlet有条件地渲染几个模板中的一个

  •  1
  • PVG  · 技术社区  · 2 年前

    我里面有3个模板 tempaltes.component . 在…内 item.component 我需要有条件地选择其中一个模板,并将其传递给 header.component 要渲染,但我的代码有问题,请帮忙。

    这是完整的代码 stackblitz

    tempaltes.component.html

    <ng-template #templateA let-item>
      <p>{{ item.name }} Template A content here...</p>
    </ng-template>
    
    <ng-template #templateB let-item>
      <p>{{ item.name }} Template B content here...</p>
    </ng-template>
    
    <ng-template #templateC let-item>
      <p>{{ item.name }} Template C content here...</p>
    </ng-template>
    

    tempaltes.component.ts

    @Component({
      selector: 'app-templates',
      templateUrl: './templates.component.html',
      standalone: true,
      imports: [],
    })
    export class TemplatesComponent {
      @ViewChild('templateA') templateA!: TemplateRef<any>;
      @ViewChild('templateB') templateB!: TemplateRef<any>;
      @ViewChild('templateC') templateC!: TemplateRef<any>;
    }
    

    item.component.html

    <app-header [headerTemplate]="selectedTemplate" [item]="item" />
    

    item.component.ts

    @Component({
      selector: 'app-item',
      templateUrl: './item.component.html',
      standalone: true,
      imports: [CommonModule, HeaderComponent],
      providers: [TemplatesComponent],
    })
    export class ItemComponent {
      templatesComponent = inject(TemplatesComponent);
    
      @Input() item!: Item;
      selectedTemplate: TemplateRef<any> | null = null;
    
      ngOnInit() {
        if (this.item.type) {
          this.selectTemplate();
        }
      }
    
      selectTemplate(): void {
        if (this.item.type === 'type-a') {
          this.selectedTemplate = this.templatesComponent.templateA;
        } else if (this.item.type === 'type-b') {
          this.selectedTemplate = this.templatesComponent.templateB;
        } else if (this.item.type === 'type-c') {
          this.selectedTemplate = this.templatesComponent.templateC;
        }
      }
    }
    

    header.component.html

    <ng-container *ngTemplateOutlet="headerTemplate; context: { $implicit: item }"></ng-container>
    

    头组件.ts

    
    @Component({
      selector: 'app-header',
      templateUrl: './header.component.html',
      standalone: true,
      imports: [CommonModule],
    })
    export class HeaderComponent {
      @Input() headerTemplate: TemplateRef<any> | null = null;
      @Input() item!: Item;
    }
    

    我认为问题在内部 tempaltes.component.ts 和/或 item.component.ts .

    1 回复  |  直到 2 年前
        1
  •  2
  •   Naren Murali    2 年前

    你不能像那样插入组件并访问视图(在你的代码中,模板组件是空的),你需要将它放在组件的html中,并使用视图子级进行访问,请在下面找到一个工作示例,我也更改为 ngAfterViewInit 由于模板将始终存在,如果您在 ngOnInit 该视图将被取消初始化,并将为null。

    html

    <p>{{ item.id }} - {{ item.name }} - {{ item.email }}</p>
    <app-header [headerTemplate]="selectedTemplate" [item]="item" />
    <app-templates #templates></app-templates>
    

    ts

    import { CommonModule } from '@angular/common';
    import {
      Component,
      Input,
      TemplateRef,
      inject,
      ViewChild,
    } from '@angular/core';
    import { Item } from '../services/data.service';
    import { HeaderComponent } from '../header/header.component';
    import { TemplatesComponent } from '../templates/templates.component';
    
    @Component({
      selector: 'app-item',
      templateUrl: './item.component.html',
      standalone: true,
      imports: [CommonModule, HeaderComponent, TemplatesComponent],
      providers: [TemplatesComponent],
    })
    export class ItemComponent {
      @ViewChild(TemplatesComponent) templatesComponent: TemplatesComponent;
    
      @Input() item!: Item;
      selectedTemplate: TemplateRef<any> | null = null;
    
      ngAfterViewInit() {
        if (this.item.type) {
          this.selectTemplate();
        }
      }
    
      selectTemplate(): void {
        console.log(this.templatesComponent);
        if (this.item.type === 'type-a') {
          this.selectedTemplate = this.templatesComponent.templateA;
        } else if (this.item.type === 'type-b') {
          this.selectedTemplate = this.templatesComponent.templateB;
        } else if (this.item.type === 'type-c') {
          this.selectedTemplate = this.templatesComponent.templateC;
        }
      }
    }
    

    stackblitz

    推荐文章