Angular 为什么用星号 (*)

Angular why asterisk (*)

在Angular文档* and template中,我们知道*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中设计一个奇怪的符号星号(*)呢?

Asterisk 语法是一种语法糖,用于更冗长的模板语法,指令扩展到底层,您可以自由使用这些选项中的任何一个。

引自docs

The asterisk is "syntactic sugar". It simplifies ngIf and ngFor for both the writer and the reader. Under the hood, Angular replaces the asterisk version with a more verbose form.

The next two ngIf examples are effectively the same and we may write in either style:

<!-- 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>

Angular 以特殊方式处理模板元素。 * 语法是一种快捷方式,可让您避免编写整个 <template> 元素。让我告诉你它是如何工作的。

使用这个

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

将其翻译成

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

然后转换为

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

还有 Agular 的结构指令,如 ngForngIf 等。以 * 为前缀只是为了将它们与其他自定义指令和组件区分开来

see more here

Angular2 提供了一种特殊的指令 - Structural directives

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

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

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

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

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

来自 Angular docs

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

As with other directives, you apply a structural directive to a host element. The directive then does whatever it's supposed to do with that host element and its descendants.

结构指令很容易识别。在此示例中,星号 (*) 位于指令属性名称之前。

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