[英]How to send instance of ngFor to ngTemplate and pass into function?
[英]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>
我們將它傳遞給我們應用ngTemplateOutlet
和ngTemplateOutletContext
的元素,如下所示 -
<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 ,我發現提供了一些變量,這就是為什么我們能夠綁定變量,比如even
, index
像 -
<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.