使用基于类实例类型的模板

问题描述 投票:2回答:2

我正在尝试显示基于类数组的模板。我不确定该怎么做。

我创建了两个模板,这些模板将被for循环引用。模板看起来像这样:

<ul>
  <li *ngFor="let item of items">
    <!-- Show one of the templates here -->
  </li>
</ul>

<ng-template #buttonTemplate>
  <button>Some Text</button>
</ng-template>

<ng-template #linkTemplate>
  <a href="">Some Text</a>
</ng-template>

接下来,我创建了一个看起来像这样的javascript组件:

@Component({ /* Options */ })
export class MyComponent {
  constructor() {
    this.items = [
      new ButtonClass(),
      new LinkClass(),
      new ButtonClass()
    ]
  }
}

[现在,当项目为#buttonTemplate时我如何使用instanceof ButtonClass而当项目为#linkTemplate时如何使用instanceof LinkClass

javascript angular
2个回答
3
投票

您可以使用*ngIf then else

<ul>
  <li *ngFor="let item of items">
     <ng-container *ngIf="item instanceOf LinkClass; then buttonTemplate else linkTemplate"></ng-container>
  </li>
</ul>

<ng-template #buttonTemplate>
  <button>Some Text</button>
</ng-template>

<ng-template #linkTemplate>
  <a href="">Some Text</a>
</ng-template>

具有两个以上的模板:

<ul>
  <li *ngFor="let item of items">
     <ng-container *ngIf="item instanceOf XXX; then template1"></ng-container>
     <ng-container *ngIf="item instanceOf XXX; then template2"></ng-container>
     <ng-container *ngIf="item instanceOf XXX; then template3"></ng-container>
     <ng-container *ngIf="item instanceOf XXX; then template4"></ng-container>
  </li>
</ul>

要将数据传递到模板,您需要这样做:

<ng-container [ngTemplateOutletContext]="{myData:item}"
    [ngTemplateOutlet]="item instanceOf XXX ? template_A: null"></ng-container>

<ng-template #template_A let-myData='myData'>
  {{ myData.name }}
</ng-template>

EDIT:您不能在HTML中使用instance of。因此,您至少有两种选择:

  • 使用函数来声明类的相等性:
*ngIf="isInstanceOfXXX(item); then X else X"

isInstanceOfXXX(item:any): item is ClassX{
   return item instance of ClassX;
}
  • 映射您的项目以添加一个内部带有类名称的新字段:
items = items.map(item => ({...item,type: item.constructor.name}))

并且在您的html中:

*ngIf="item.type === 'ClassX'; then X else X"

但是要小心最后一种方法,ClassX.name是ES6功能,因此在IE11中不起作用


0
投票

我最终使用的是@ViewChild,这使我可以将模板返回到ngTemplateOutlet

所以我的html除了ng-template循环中的新for没什么变化。

<ul>
  <li *ngFor="let item of items">
    <ng-template *ngTemplateOutlet="item | getTemplate : buttonTemplate : linkTemplate; context: {$implicit: {model: item, /* other properties */}}">
  </li>
</ul>

<ng-template #buttonTemplate let-item>
  <button>{{item.model.text}}</button>
</ng-template>

<ng-template #linkTemplate let-item>
  <a href="{{item.model.endpoint}}">{{item.model.text}}</a>
</ng-template>

在我的JavaScript / TypeScript中,我添加了@ViewChild,以及一个接受项目并测试引用并返回正确的TemplateRef的函数。

@Component({ /* Options */ })
export class MyComponent {

  @ViewChild('buttonTemplate', { static: true })
  public buttonTemplate

  @ViewChild('linkTemplate', { static: true })
  public linkTemplate

  public items = [
    new ButtonClass(),
    new LinkClass(),
    new ButtonClass()
  ]

  getTemplate(item) {
    if(item instanceof ButtonClass) return this.buttonTemplate
    if(item instanceof LinkClass) return this.linkTemplate
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.