如何将内容子项的每个子项包装在Angular中自己的元素中

时间:2018-05-19 01:24:54

标签: html angular typescript

假设我想制作一个安排其所有孩子的组件。我应该能够提供元素,例如:

<app-layout-list>
  <p>foo</p>
  <p>bar</p>
  <p>etc</p>
</app-layout-list>

并且在app-layout-list中应该执行类似

的操作
<ul>
  <li>
    <ng-content>
  </li>
<ul>

为每个内容生成一个li。这可能是使用ng-content还是我需要做一些更复杂的事情?

1 个答案:

答案 0 :(得分:3)

当然可以! :)

这很简单! (Directly to the Stackplitz Demo

Angular为这类问题提供了完美的API。

基本上你想要的是将你的<ng-content></ng-content>分成不同的部分。

首先,您必须通过指令标记要在<li>元素中显示的部分。实现此目标的最佳方法是通过Structural Directive,因为它会为我们生成<ng-template></ng-template>,我们以后需要这样做。

我们构建的Directive非常基础。它只在构造函数中注入TemplateRef并将模板保存在`public variable:

<强>列表item.directive.ts

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

@Directive({
  selector: '[appListItem]'
})
export class ListItemDirective {

  public itemTemplate: TemplateRef<any>;

  constructor(private templateRef: TemplateRef<any>) {
    this.itemTemplate = this.templateRef;
  }

}

使用此指令,我们将html元素标记为<li>元素。

<强> app.component.ts

<app-layout-list>
  <p *appListItem>foo</p>
  <p *appListItem>bar</p>
  <p *appListItem>etc</p>
</app-layout-list>

LayoutListComponent内,我们通过@ContentChildren(ListItemDirective) listItems

获取投影元素

<强>布局list.component.ts

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

@Component({
  selector: 'app-layout-list',
  templateUrl: './layout-list.component.html',
  styleUrls: ['./layout-list.component.css']
})
export class LayoutListComponent {
  @ContentChildren(ListItemDirective) listItems: QueryList<ListItemDirective>;
}

最后在Component template内,我们正在遍历listItems,并将每个项目的TemplateReference放在ngTemplateOutlet

<强>布局list.component.html

<ul>
  <ng-container *ngFor="let item of listItems">
    <li>
      <ng-container [ngTemplateOutlet]="item.itemTemplate"></ng-container>
    </li>
  </ng-container>
</ul>

DEMO: Stackblitz Demo

GITHUB SOURCE: Github Source