【问题标题】:How to wrap each child of contentchildren in their own elements in Angular如何在 Angular 中将 contentchildren 的每个孩子包装在他们自己的元素中
【发布时间】:2018-10-29 11:08:29
【问题描述】:

假设我想创建一个组件来安排它的所有子组件。我应该能够提供元素,例如:

<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 还是我需要做一些更复杂的事情?

【问题讨论】:

    标签: html angular typescript


    【解决方案1】:

    当然可以! :)

    而且非常简单! (Directly to the Stackplitz Demo)

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

    基本上你想要的是将你的&lt;ng-content&gt;&lt;/ng-content&gt; 分成不同的部分。

    首先,您必须通过指令标记要在&lt;li&gt; 元素中显示的部分。实现这一目标的最佳方式是通过Structural Directive,因为它会为我们生成&lt;ng-template&gt;&lt;/ng-template&gt;,我们稍后需要它。

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

    list-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;
      }
    
    }

    通过这个指令,我们标记了我们喜欢放置在 &lt;li&gt; 元素中的 html 元素。

    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 获取投影元素

    layout-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

    layout-list.component.html

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

    演示: Stackblitz Demo

    GITHUB 源: Github Source

    【讨论】:

    • Stackbltiz 演示不可用
    • 在 layout-list.component.html item.listTemplate 应该是 item.itemTemplate,但是你的回答对我很有帮助,谢谢
    • @SplitterAlex - StackBlitz 演示不可用,再次
    • @GeoffJames - StackBlitz 演示再次运行。我还在 Github 上添加了指向源代码的链接。
    • 现在尝试用 *ngFor 转换 &lt;p *appListItem&gt;foo&lt;/p&gt;
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-11
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 2023-03-29
    • 1970-01-01
    相关资源
    最近更新 更多