How to wrap each child of contentchildren in their own elements in Angular

前端 未结 1 2066
慢半拍i
慢半拍i 2021-01-19 17:21

lets say I want to make a component that arranges all of its children. I should be able to provide the element for example:


  

        
相关标签:
1条回答
  • 2021-01-19 17:42

    Of course you can! :)

    And it is very simple! (Directly to the Stackplitz Demo)

    Angular provides a perfect API for this kind of problems.

    Basically what you want is to splitt your <ng-content></ng-content> in their different parts.

    First of all you have to mark the portions you want to display inside the <li> elements via a directive. The best way to achive this is via a Structural Directive, because it generates a <ng-template></ng-template> for us, which we need later.

    The Directive we build is very basic. It only injects the TemplateRef in the constructor and saves the template in a `public variable:

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

    With this directive we mark our html elements which we like to place inside a <li> element.

    app.component.ts

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

    Inside LayoutListComponent we get hold of the projected elements via @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>;
    }

    Finally inside the Component template we are iterating through the listItems and placing the TemplateReference of every item inside a 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>

    DEMO: Stackblitz Demo

    GITHUB SOURCE: Github Source

    0 讨论(0)
提交回复
热议问题