七爪源码:Angular 结构指令及其微语法

Angular 结构指令及其微语法

七爪源码:Angular 结构指令及其微语法

你有没有想过 *ngIf 和 *ngFor 的星号前缀是什么? 这称为结构性指令。

在本文中,我将向您展示您何时需要它以及它是如何工作的。

我还将做第 2 部分,向您展示如何创建自己的结构指令。


模板是结构

让我们开始定义它是什么。

结构指令是具有结构的指令。 该结构是一个 ng 模板。 当你编写

Text

时,你是在告诉 Angular “_declare div 标签的结构,带有一个段落标签,带有字符串“Text”,并渲染它_” .

但是当你将它包装在

Text

中时,你是在告诉 Angular “_declare div 标签的结构,使用 一个段落标签,带有字符串“Text”_”。 但请注意,现在我们并没有告诉 Angular 渲染它。

现在,在 中放置一个指令,你就有了一个结构指令:

Text


合成糖

这就是 ngIf 的工作原理。 Angular 解析 ,生成一个 TemplateRef,它被注入到 NgIf 指令中。如果传递给 ngIf 的条件为真,则呈现模板。

但是每次我们想使用 NgIf 或任何其他需要 ng-template 的指令时创建一个 ng-template 会很烦人。所以 Angular 团队创造了合成糖。就像一条捷径。

当您在指令前加上星号时,Angular 会将其包装在 ng-template 中并将指令应用于 ng-template。所以Abc,变成Abc

这只是合成糖。如果您愿意,您可以编写不带星号前缀的整个应用程序。


只允许一个

了解了它的工作原理,您现在可以理解为什么我们只能对每个元素使用一个结构指令。如果你在同一个元素中使用 *ngIf 和 *ngFor,Angular 会如何去糖呢?先 ngIf 再 ngFor?相反?两者都在同一个模板中?


微语法

说到ngFor,好像比ngIf要复杂的多吧?我见过一些非常复杂的 ngFor 表达式,比如传递一个 trackBy 函数,管道一个 observable 数组,获取索引,并检查它是否是最后一个元素。

{{ item }}

最初,我认为这是 ngFor 特有的术语,但事实并非如此。 这是一个完整记录的语法,适用于任何结构指令,甚至是您最终创建的指令。 它被称为“结构指令微语法”。 (有点明显)

结构指令微语法将表达式用分号 (;) 分开。 在我们的 NgFor 示例中,我们有 4 个表达式:

  1. 让列表项$ | 异步
  2. trackBy:trackByFn
  3. 让 itemIndex = 索引
  4. 让 islast = 最后


声明

以 let 开头的表达式是变量声明。 您在 let 之后立即声明变量名称,并使用等号 (=) 将其指向导出指令上下文中的变量名称。

那是很多,对不起。

我的意思是当我们渲染一个 时,我们可以选择传递一个上下文对象。 并且这个上下文对象的属性被传递给模板。 上下文对象可以有多个显式变量和一个隐式变量。





  

#{{ itemIndex }} - {{ item }}

它就像一个 JavaScript 函数,我们有参数,我们声明了它,因此非常显式,我们有 this,它是一个隐式变量,即使我们没有声明它也存在。

function example(itemIndex, isLast) {
  // Explicit
  console.log(itemIndex, isLast);
  // Implicit
  console.log(this);
}

在一个函数中,你可以有任意多的参数,但只有一个 this。 就像这样,在 ng-template 中,您可以拥有任意数量的显式变量,但只有一个隐式变量。

当你不指向任何导出的变量时,你会得到隐式变量。 例如,let item 正在获取隐式变量。 但是让 isLast = last 得到显式的最后一个变量,让 itemIndex = index 得到显式的索引变量。

对变量进行脱糖处理后,我们得到:


    

#{{ itemIndex }} - {{ item }}

The end

关键表达式

带有两个参数和它们之间的可选冒号 (:) 的表达式是键表达式。 表达式(右侧)被分配给前面带有前缀的键(左侧)。


让我们看一些例子。

在 \*ngIf="condition; else otherTemplate 中,对于 else otherTemplate 表达式:

  • ngIf 是前缀
  • 否则是关键
  • otherTemplate 是表达式
七爪源码:Angular 结构指令及其微语法

这被脱糖为

七爪源码:Angular 结构指令及其微语法

在 *ngFor="let item of list; trackBy: trackByFn,对于 trackBy: trackByFn 表达式:

  • ngFor 是前缀
  • trackBy 是关键
  • trackByFn 是表达式

这被脱糖为

此外,对于那个 NgFor example,list 的 let item 中的 list 也是一个关键表达式。

  • ngFor 是前缀
  • of 是关键
  • 列表是表达式

这被脱糖为


本地绑定

最后要提到的是表达式末尾的可选 as 关键字。 它声明一个模板变量并将表达式的结果映射到它。

*ngIf="condition as value" 变为

七爪源码:Angular 结构指令及其微语法

七爪源码:Angular 结构指令及其微语法

结论

而已。 您现在了解了结构指令的工作原理以及如何分析它们的微语法。

我将写另一篇文章,介绍如何从头开始编写自定义结构指令以及如何告诉 Angular 编译器对其上下文进行类型检查。

祝你有美好的一天,很快见到你!

发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章