簡體   English   中英

了解可重用組件中的 ngTemplateOutlet、@ContentChild、ng-container

[英]Understanding ngTemplateOutlet, @ContentChild, ng-container in Reusable Component

我花了更多時間試圖理解以下博客文章在 Angular 中使用 NgTemplateOutlet 創建可重用組件

上面帖子的工作代碼可以在stackblitz找到。

UsageExample組件中,調用了card-or-list-view組件。 提供了我非常理解的項目模式輸入參數。

現在我不明白的是如何

<ng-container *cardItem="let item">
        <h1>{{item.header}}</h1>
        <p>{{item.content}}</p>
      </ng-container>
      <span *listItem="let item">
        <h1>{{item.header}}</h1>
        <p>{{item.content}}</p>
      </span>

UsageExample模板中替換

<ng-container *ngSwitchCase="'card'">
    <div *ngFor="let item of items" style="margin: 5px;border: black 1px solid">
      <ng-container *ngTemplateOutlet="cardItemTemplate; context: {$implicit: item}">
      </ng-container>
    </div>
  </ng-container>
  <ul *ngSwitchCase="'list'">
    <li *ngFor="let item of items">
      <ng-container *ngTemplateOutlet="listItemTemplate; context: {$implicit: item}"></ng-container>
    </li>
  </ul>

CardOrListViewComponent組件的模板中。 CardOrListViewComponent組件中,聲明了兩個指令

@ContentChild(CardItemDirective, {read: TemplateRef}) cardItemTemplate;
  @ContentChild(ListItemDirective, {read: TemplateRef}) listItemTemplate;

並在其模板中使用*ngTemplateOutlet

這些指令如何被替換

<ng-container *cardItem="let item">
        <h1>{{item.header}}</h1>
        <p>{{item.content}}</p>
      </ng-container>
      <span *listItem="let item">
        <h1>{{item.header}}</h1>
        <p>{{item.content}}</p>
      </span>

UsageExample組件中。

*cardItem*listItem如何連接到CardOrListViewComponent組件中的兩個@ContentChild指令。 他們的名字甚至都不相似。

首先,Angular 結構指令有兩種形式我們可以使用:

1) 加糖版本

<div *ngIf="foo">bar</div>

2) 脫糖版

<ng-template [ngIf]="foo">
  <div>bar</div>
</ng-template>

回到你的例子:

<ng-container *cardItem="let item">
  <h1>{{item.header}}</h1>                            sugar
  <p>{{item.content}}</p>
</ng-container>

       ||
       \/

<ng-template cardItem let-item>
  <ng-container>
    <h1>{{item.header}}</h1>                         de-sugar
    <p>{{item.content}}</p>
  </ng-container>
</ng-template>

其次,通常的做法是通過@ViewChild (-dren)| 獲取對模板中某些內容的引用。 @ContentChild (-dren) 裝飾器。

我們可以查詢匹配模板元素的指令。 Angular 總是匹配我們模板的脫糖版本。 所以指令:

@Directive({
  selector: '[cardItem]'
})
export class CardItemDirective {}

匹配模板:

  selector: '[cardItem]' 
               ||
               \/
<ng-template cardItem let-item>

如果您不想要有關我們可以查詢的所有可能情況,請遵循以下答案

現在我們知道通過使用@ContentChild 查詢:

@ContentChild(CardItemDirective) cardItemTemplate;

我們得到CardItemDirective實例,但我們想得到TemplateRef以便在*ngTemplateOutlet使用它。

這是read選項可以解決的地方:

@ContentChild(CardItemDirective, {read: TemplateRef}) cardItemTemplate;
                                     \/
         please give us TemplateRef instance from the element 
         that matches CardItemDirective selector

最后,有了TemplateRef我們可以在ngTemplateOutlet指令的幫助下渲染它並傳遞我們想要的任何上下文:

<div *ngFor="let item of items">
  <ng-container *ngTemplateOutlet="cardItemTemplate; context: {$implicit: item}">

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM