javascript - 在 *ngFor 的情况下,是什么为 ngTemplate 提供了上下文?

标签 javascript angular ngfor angular2-directives ng-template

我对 ngTemplateOutletContext 有一些困惑,特别是如何传递给 ngTemplate或者谁把它传给 ngTemplate它围绕着 *ngFor 所在的元素被应用。当我将其与方式进行比较时,当我们明确传递 which 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 传递的内容一样的上下文(或任何其他父容器)像这样 -
enter image description here
我在这里的理解是我们删除了ng-templatengTemplateOutlet 中提供在 ngTemplateOutletContext 中传递了上下文.我们创建局部变量以在模板本身中使用。

问题

当我们使用 *ngFor喜欢 -
<p *ngFor="let number of data">
  {{number}}
</p>
并通过以下方式对其进行脱糖-
<ng-template #temp ngFor [ngForOf]="data" let-number>
  <p>{{number}}</p>
</ng-template>
在哪里 data ts 中的变量文件是 data = [1,2,3]The question is -
1.) 谁为这个脱糖的 ng-template 提供值(上下文)以便它能够将 let-number 绑定(bind)到 $implicit 属性。我查看了ngForOfContext ,在那里我发现提供了一些变量,这就是为什么我们能够绑定(bind)变量,如 even , index喜欢 -
<p *ngFor="let number of data; let i=index; let isEven=even">
但是在这种情况下谁将这些变量提供给 ng-template . (当我们显式传递模板时,父容器(此处为 div)提供了我们之前看到的上下文)
2.) 当我们设置 ngForTemplate它需要一个类型为 TemplateRef 的模板如此处给出-
enter image description here
使用 p *ngFor 指令允许它,但设置 p 的引用在使用 ngFor 的脱糖版本时显式不允许它,即 -
<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>
但它无法识别 ptemplatengForTemplate .如果无法识别 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>
内部 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 以外的任何东西,我们会得到一个错误。
如果我们查看 source code of the ngFor directive我们可以看到它在它的构造函数中需要一个 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 指令。
希望这能回答你的问题。

关于javascript - 在 *ngFor 的情况下,是什么为 ngTemplate 提供了上下文?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67832209/

相关文章:

angular - 在 Angular 中使用指令 ngIf 或指令 ngFor 时显示空白页面

php - 为具有屏幕截图功能的 Web 应用程序提供错误报告工具?

javascript - 正则表达式和 JavaScript : find word with accents

javascript - 如何将后退按钮实现为动态生成的 html?

javascript - 如何从 Angular Locale 获取有关时间格式 (12/24) 的信息?

angular - *NgFor 不显示数据

javascript - 如何在不使用each的情况下访问复选框数组的第一个元素?

angular - Response.json() 使用接口(interface)绑定(bind)到单个对象 - RxJs/Observable 失败

Angular4 在组件之间传递信息

angular - 使用嵌套的 *ngFor 从对象数组和键字符串数组生成表