Paw*_*rma 7 javascript angular2-directives ng-template ngfor angular
我对它有一些困惑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>
Run Code Online (Sandbox Code Playgroud)
我们将它传递给我们已经应用的某个元素,ngTemplateOutlet就像ngTemplateOutletContext这样 -
<div [ngTemplateOutlet]="temp" [ngTemplateOutletContext]="{$implicit: 4}">
</div>
Run Code Online (Sandbox Code Playgroud)
(我们应该使用ng-container上述操作,因为它不会在 DOM 中,但这里与我无关。)
现在,temp ngTemplate将具有上下文div(或任何其他父容器)传递的上下文,如下所示 -
我在这里理解的是,我们消除了传入的上下文ng-template中提供的内容。我们创建在模板本身中使用的局部变量。ngTemplateOutletngTemplateOutletContext
问题
当我们使用*ngFor像 -
<p *ngFor="let number of data">
{{number}}
</p>
Run Code Online (Sandbox Code Playgroud)
它通过以下方式脱糖-
<ng-template #temp ngFor [ngForOf]="data" let-number>
<p>{{number}}</p>
</ng-template>
Run Code Online (Sandbox Code Playgroud)
文件data中的变量在哪里tsdata = [1,2,3]
The question is-
1.)谁向此脱糖提供值(上下文),ng-template以便它能够将 let-number 绑定到 $implicit 属性。我查看了ngForOfContext,在那里我发现提供了一些变量,这就是为什么我们能够绑定变量even,index例如 -
<p *ngFor="let number of data; let i=index; let isEven=even">
Run Code Online (Sandbox Code Playgroud)
但在这种情况下谁将这些变量提供给ng-template. (当我们显式传递模板时,父容器(div此处)提供了我们之前看到的上下文)
2.)当我们设置时,此处给出的ngForTemplate类型模板 -TemplateRef
p与 *ngFor 指令一起使用允许这样做,但p在使用脱糖版本时显式设置引用ngFor则不允许这样做,即 -
<ng-template #temp ngFor [ngForOf]="data" [ngForTemplate]="pTemplate" let-number>
Run Code Online (Sandbox Code Playgroud)
哪里pTemplate-
<p #pTemplate *ngFor="let number of data; let i=index; let isEven=even">
{{number}} {{i}} {{isEven}}
</p>
Run Code Online (Sandbox Code Playgroud)
但它不ptemplate识别ngForTemplate. 如果它不能识别pTemplate为有效的ngForTemplate,它如何能够消除p它*ngFor的旧版本?
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>
Run Code Online (Sandbox Code Playgroud)
内部 html 是一个 ng-template。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>
Run Code Online (Sandbox Code Playgroud)
因此 ngFor 指令提供了该模板的上下文。该上下文具有类型ngForOfContext
我们可以通过自己提供上下文来将此模板与 ngTemplateOutlet 一起使用:
<ng-container *ngTemplateOutlet="pTemplate;context:{$implicit:43,even:true,index:2}">
</ng-container>
Run Code Online (Sandbox Code Playgroud)
但 *ngFor 语法是 ngTemplate 的语法糖。我们可以在不加糖的情况下使用它,如下所示:
<ng-template ngFor [ngForOf]="data" let-number let-isEven="even" let-i="index">
<p [class.even]="isEven">{{i}} : {{number}}</p>
</ng-template>
Run Code Online (Sandbox Code Playgroud)
这里 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>
Run Code Online (Sandbox Code Playgroud)
但如果在输入中使用脱糖语法,ngForTemplate我们必须声明第二个 ng-template 元素。因为如果我们尝试在 ng-template 之外的任何其他内容上应用不带 * 的 ngFor 指令,我们会收到错误。
如果我们查看ngFor 指令的源代码,我们可以看到它的构造函数中需要一个 templateRef 。但此模板引用的值也由 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>
Run Code Online (Sandbox Code Playgroud)
在本例中,我们有 2 个模板,但只使用了一个,因此我们放置 ngFor 的模板不需要上下文,其唯一目的是能够调用 ngFor 指令。
希望这能回答您的问题。
| 归档时间: |
|
| 查看次数: |
6503 次 |
| 最近记录: |