簡體   English   中英

在 *ngFor 的情況下,是什么為 ngTemplate 提供了上下文?

[英]What gives the context to ngTemplate in case of *ngFor?

我對ngTemplateOutletContext有一些困惑,特別是它是如何傳遞給ngTemplate的,或者誰將它傳遞給ngTemplate ,它圍繞着應用了*ngFor的元素。 當我將其與方式進行比較時,當我們明確傳遞要渲染的ngTemplate時,就會產生混淆。

這是我認為當我們明確傳遞模板時會發生的事情 -

假設我們有一個ngContainer / ngTemplate / ( Literally any HTML element as ngTemplateOutlet & ngTemplateOutletContext can be applied to any element) ,現在我們選擇顯式提供我們之前創建的模板。 像這樣 -

<ng-template #temp let-number>
  <p>{{number}}</p>
</ng-template>

我們將它傳遞給我們應用ngTemplateOutletngTemplateOutletContext的元素,如下所示 -

<div [ngTemplateOutlet]="temp" [ngTemplateOutletContext]="{$implicit: 4}">
</div>

(我們應該使用ng-container進行上述操作,因為它不會在 DOM 中,但我在這里不關心。)

現在temp ngTemplate將在那里具有與div (或任何其他父容器)傳遞的內容一樣的上下文 -

在此處輸入圖像描述

我在這里理解的是,我們刪除了在 ngTemplateOutlet 中提供的ng-template ,並在ngTemplateOutlet中傳遞了ngTemplateOutletContext 我們創建局部變量以在模板本身中使用。


問題


當我們使用*ngFor時 -

<p *ngFor="let number of data">
  {{number}}
</p>

並通過以下方式對其進行脫糖-

<ng-template #temp ngFor [ngForOf]="data" let-number>
  <p>{{number}}</p>
</ng-template>

其中ts文件中的data變量是data = [1,2,3]

The question is ——

1.)誰為這個脫糖的ng-template提供值( context ),以便它能夠將 let-number 綁定到 $implicit 屬性。 我查看了ngForOfContext ,我發現提供了一些變量,這就是為什么我們能夠綁定變量,比如evenindex像 -

<p *ngFor="let number of data; let i=index; let isEven=even">

但是在這種情況下,誰將這些變量提供給ng-template (當我們顯式傳遞模板時,父容器(這里是div )提供了我們之前看到的上下文)

2.)當我們設置ngForTemplate時,它需要一個 TemplateRef 類型的TemplateRef ,如下所示-

在此處輸入圖像描述

p與 *ngFor 指令一起使用允許它,但在使用ngFor的脫糖版本時顯式設置p的引用不允許它,即 -

<ng-template #temp ngFor [ngForOf]="data" [ngForTemplate]="pTemplate" let-number>

pTemplate在哪里 -

<p #pTemplate *ngFor="let number of data; let i=index; let isEven=even">
  {{number}} {{i}} {{isEven}}
</p>

但它無法識別ptemplate中的ngForTemplate 如果它不能將pTemplate識別為有效的ngForTemplate ,它如何能夠在它的*ngFor版本中剔除p

PS:如果我在問題之前對ng-template的理解有誤,我也很樂意糾正它。

當我們使用 ngFor 指令時,例如:

<ng-container *ngFor="let number of data;let i = index;let isEven=even">
    <p [class.even]="isEven">{{i}} : {{number}}</p>
</ng-container>

內部 html 是一個 ng 模板。 ngFor 指令為循環的每次迭代提供此模板的上下文。

正如您所指出的,在 ngFor 指令上有一個 ngForTemplate 輸入。 我們可以使用它來設置在 ngFor 內部 Html 之外聲明的模板

<ng-template #pTemplate let-number let-isEven="even" let-i="index">
    <p [class.even]="isEven">{{i}} : {{number}}</p>
</ng-template>


<ng-container *ngFor="let number of data;let i = index;let isEven=even;template: pTemplate">
</ng-container>

所以 ngFor 指令為這個模板提供了上下文。 此上下文的類型為ngForOfContext

我們可以通過自己提供上下文來將此模板與 ngTemplateOutlet 一起使用:

<ng-container *ngTemplateOutlet="pTemplate;context:{$implicit:43,even:true,index:2}">
</ng-container>

但是 *ngFor 語法是 ngTemplate 的語法糖。 我們可以像這樣在沒有糖的情況下使用它:

<ng-template ngFor [ngForOf]="data"  let-number let-isEven="even" let-i="index">
    <p [class.even]="isEven">{{i}} : {{number}}</p>
</ng-template>

這里的 ng-template 仍然是每次迭代應用的模板。 我們還可以通過提供上下文在 ngTemplateOutlet 中使用它:

<ng-template #templ ngFor [ngForOf]="data"  let-number let-isEven="even" let-i="index">
    <p [class.even]="isEven">{{i}} : {{number}}</p>
</ng-template>

<ng-container *ngTemplateOutlet="templ;context:{$implicit:43,even:true,index:2}">
</ng-container>

但是如果使用帶有ngForTemplate輸入的去糖語法,我們必須聲明第二個 ng-template 元素。 因為如果我們嘗試將不帶 * 的 ngFor 指令應用於 ng-template 以外的任何東西,我們會得到一個錯誤。

如果我們查看ngFor 指令的源代碼,我們可以看到它的構造函數中需要一個 templateRef。 但是這個模板 ref 的值也是由 ngForTemplate 輸入設置的。

所以我們需要寫

<ng-template #pTemplate let-number let-isEven="even" let-i="index">
    <p [class.even]="isEven">{{i}} : {{number}}</p>
</ng-template>

<ng-template ngFor [ngForOf]="data" [ngForTemplate]="pTemplate"></ng-template>

<!-- And we cannot write : -->
<ng-container ngFor [ngForOf]="data" [ngForTemplate]="pTemplate"></ng-container>

在這種情況下,我們有 2 個模板,但只使用了一個,因此我們放置 ngFor 的模板不需要上下文,它的唯一目的是能夠調用 ngFor 指令。

希望這能回答你的問題。

暫無
暫無

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

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