1. 程式人生 > 程式設計 >angular內容投影詳解

angular內容投影詳解

目錄
  • 單內容投影
  • 多內容投影
  • 單個條件的內容投影
    • app-persons - html
    • app-persons - ts
    • 使用
    • 效果圖
  • 多個條件內容投影
    • appChildRef 調整
    • app-persons - html
    • app-persons - ts
    • 使用
    • 效果圖
  • 總結

    單內容投影

    利用ng-content來實現

    <!-- 元件 - app-content-single -->
    <div>
      <h2>標題</h2>
      <!-- 投影內容顯示位置 -->
      <ng-content></ng-content>
    </div>
    <!-- 使用 -->
    <app-content-single>
      <div>this is content</div>
    </app-content-single>
    

    多內容投影

    利用ng-content來實現

    <!-- 元件 - app-content-more -->
    <div>
      <h3>Herder Title</h3>
      <ng-content select=".header"></ng-content>
      <h3>Body Title</h3>
      <ng-content select="[body]"></ng-content>
      <h3>Default Title</h3>
      <ng-content></ng-content>
      <h3>Footer Title</h3>
      <ng-content select="footer"></ng-content>
    </div>
    <!-- 使用 -->
    <app-content-more>
      <div>this is default01</div>
      <div class="header">this is header</div>
      <div>this is default02</div>
      <div body>this is body</div>
      <div>this is default03</diJQjlAWK
    v> <footer>this is footer</footer> <div>this is default04</div> </app-content-more>

    有條件的內容投影-ng-template,ng-container,directive 等來配合實現

    單個條件的內容投影

    eg: 假設現在有一個人員列表,當某個人的money大於200的時候,額外新增元件中模板定義的內容

    定義一個 appChildRef 指令來配合 ng-template 獲取模板

    import { Directive,TemplateRef } from '@angular/core';
    @Directive({
      selector: '[appChildRef]'
    })
    export class ChildRefDirective {
      constructor(public templateRef: TemplateRef<any>) { }
    }
    

    app-persons - html

    <div class="list-item" *ngFor="let person of persons;">
      <div>Name: {{ person.name }}</div>
      <div>Money: {{ person.money }}</div>
      <div *ngIf="person.money > 200">
        <ng-container *ngIf="childRef" [ngTemplateOutlet]="childRef.templateRef"></ng-container>
      </div>
    </div>
    

    app-persons - ts

    import { Component,ContentChild,OnInit } from '@angular/core';
    import { ChildRefDirective } from '../../../../directives/child-ref.directive';
    @Component({
      selector: 'app-persons',templateUrl: './persons.component.html',styleUrls: ['./persons.component.s']
    })
    export class PersonsComponent implements OnInit {
      persons: { name: string; money: number; }[] = [
        { name: '傑克',money: 120 },{ name: '李莉',money: 210 },{ name: '張三',money: 170 },];
      @ContentChild(ChildRefDirective,{ static: true }) childRef!: ChildRefDirective;
      constructor() { }
      ngOnInit(): void { }
    }
    

    使用

    <app-persons>
      <ng-template appChildRef>
        <div style="font-size: 14px; color: red;">this is child ref content</div>
      </ng-template>
    </app-persons>
    

    效果圖

    效果圖

    多個條件內容投影

    eg: 現在希望通過 persons 資料中的欄位進行繫結內嵌的模板來顯示

    appChildRef 調整

    import { Directive,Input,TemplateRef } from '@angular/core';
    @Directive({
      selector: '[appChildRef]'
    })
    export class ChildRefDirective {
      // 接受定義模板名稱-通過這個名稱和 persons 中的render欄位對應進行顯示對應的模板內容
      @Input() appChildRef!: string;
      constructor(public templateRef: TemplateRef<any>) { }
    }
    

    app-persons - html

    <div class="list-item" *ngFor="let person of persons;let i=index;">
      <div>Name: {{ person.name }}</div>
      <div>Money: {{ person.money }}</div>
      <!-- <div *ngIf="person.money > 200">
        <ng-container *ngIf="childRef" [ngTemplateOutlet]="childRef.templateRef"></ng-container>
      </div> -->
      <div *ngIf="person.render && tempRefs[person.render]">
        <!-- 配合 ngTemplateOutlet 指令給template傳遞當前person的資料 -->
        <ng-container *ngTemplateOutlet="tempRefs[person.renderhttp://www.cppcns.com].templateRef; context: { $implicit: person,i: i }"></ng-container>
      </div>
    </div>
    

    app-persons - ts

    import { Component,ContentChildren,OnInit,QueryList } from '@angular/core';
    import { ChildRefDirective } from '../../../../directives/child-ref.directive';
    @Component({
      selector: 'app-form-unit',templateUrl: './form-unit.component.html',styleUrls: ['./form-unit.component.scss']
    })
    export class FormUnitComponent implements OnInit {
      persons: { name: string; money: number; render?: string; }[] = [
        { name: '傑克',money: 120,render: 'temp1' },money: 210,render: 'temp2' },money: 170,render: 'temp3' },];
      // @ContentChild(ChildRefDirective,{ static: true }) childRef!: ChildRefDirective;
      @ContentChildren(ChildRefDirective) childrenRef!: QueryList<ChildRefDirective>;
      get tempRefs() {
        const aObj: any = {};
        this.childrenRef.forEach(template => {
          const key: string = template.appChildRef;
          aObj[key] = template;
        })
        return aObj;
      }
      constructor() { }
      ngOnInit(): void { }
    }
    

    使用

    <app-persons>
      <nJQjlAWKg-template appChildRef="temp1" let-person let-index="i">
        <div style="font-size: 14px; color: red;">{{index}}-{{person.name}}: this is temp1</div>
      </ng-template>
      <ng-template appChildRef="temp2" let-person let-index="i">
        <div style="font-size: 14px; color: green;">{{index}}-{{person.name}}: this is temp2</div>
      </ng-template>
      <ng-template appChildRef="temp3" let-person let-index="i">
        <div style="font-sizeJQjlAWK: 14px; color: orange;">{{index}}-{{person.name}}: this is temp3</div>
      </ng-template>
    </app-persons>
    

    效果圖

    效果圖

    總結

    本篇文章就到這裡了,希望能夠給你帶來幫助,也希望您能夠多多關注我們的更多內容!