Angular为什么要用星号(*)

Angular why asterisk (*)

本文关键字:为什么 Angular      更新时间:2023-09-26

在Angular文档*和模板中,我们知道*ngIf、*ngSwitch、*ngFor可以扩展为ng-template标签。我的问题是

我认为没有*ngIfngFor也可以被Angular引擎翻译和扩展为模板标签。

以下代码

<hero-detail *ngIf="currentHero" [hero]="currentHero"></hero-detail>

相同
<ng-template [ngIf]="currentHero">
  <hero-detail [hero]="currentHero"></hero-detail>
</ng-template>

那么为什么要在Angular中设计一个奇怪的星号(*)呢?

星号语法是冗长的模板语法的语法糖,指令扩展到底层,您可以自由使用这些选项。

引用自文档:

星号为"语法糖"。它简化了ngIf和ngFor for作者和读者都有。在底层,Angular替换了星号版本,格式更详细。

下面两个ngIf的例子实际上是一样的,我们可以用任意一种风格来写:

<!-- Examples (A) and (B) are the same -->
<!-- (A) *ngIf paragraph -->
<p *ngIf="condition">
  Our heroes are true!
</p>
<!-- (B) [ngIf] with template -->
<template [ngIf]="condition">
  <p>
    Our heroes are true!
  </p>
</template>

Angular2提供了一种特殊的指令——结构指令

结构指令基于<template>标签。

属性选择器前的*表示应该应用一个结构指令,而不是普通的属性指令或属性绑定。Angular2内部将语法扩展为一个显式的<template>标签。

因为final还有<ng-container>元素,它可以类似于<template>标记使用,但支持更常见的简写语法。例如,当两个结构指令应用于单个元素时,这是必需的,这是不支持的。

<ng-container *ngIf="boolValue">
  <div *ngFor="let x of y"></div>
</ng-container>

Angular以一种特殊的方式对待模板元素。*语法是一种快捷方式,可以避免编写整个<template>元素。让我给你演示一下它是如何工作的。

使用这个

*ngFor="let t of todos; let i=index"

翻译成

template="ngFor: let t of todos; let i=index" 

然后转换成

<template ngFor [ngForOf]="todos" .... ></template>

也适用于像ngFor, ngIf这样的结构指令。前缀*只是为了区别于其他自定义指令和组件

点击这里查看更多

From Angular docs:

结构指令负责HTML布局。它们塑造或重塑DOM的结构,通常是通过添加、删除或操作元素。

与其他指令一样,您将结构指令应用于宿主元素。然后指令就可以做它应该做的任何事情宿主元素和它的后代。

结构指令很容易识别。在本例中,指令的属性名前加一个星号(*)。

<p *ngIf="userInput">{{username}}</p>

有时您可能需要<a *ngIf="cond">,例如,当它只有一个标签时。有时你可能想把ngIf放在多个标签周围,而不需要一个真正的标签作为包装器,这会导致你的<template [ngIf]="cond">标签。angular怎么知道它是否应该在最终结果html中渲染ngIf指令的所有者呢?所以这不仅仅是让代码更清晰。