angular - Angular 在哪里为 *ngIf 定义 "as local-var"行为?

标签 angular rxjs open-source

我试图了解 ngIf 的“as local-var”可选行为在哪里定义,例如: *ngIf="user$ | async as user"

尝试查看源代码中明显的地方,比如 https://github.com/angular/angular/blob/master/packages/common/src/directives/ng_if.ts

但代码中没有任何内容,只有文档。

有谁知道这种魔法发生在代码中的什么地方?

最佳答案

是的,模板编译期间发生的事情很神奇。

下面的模板

<div *ngIf="user$ | async as user"></div>

只是糖分:

<ng-template [ngIf]="user$ | async" let-user="ngIf">
  <div></div>
</ng-template>

所以答案是:下面的字符串将值传递给这个变量:

this._context.$implicit = this._context.ngIf = condition;
                                ^^^^^^^^^^^^^

https://github.com/angular/angular/blob/master/packages/common/src/directives/ng_if.ts#L115

例如,我们可以创建结构指令 ngVar:

@Directive({
  selector: '[ngVar]',
})
export class VarDirective {
  @Input()
  set ngVar(context: any) {
    this.context.$implicit = this.context.ngVar = context;
                              ^^^^^^^^^^^^^^^^
    this.updateView();
  }

  context: any = {};

  constructor(private vcRef: ViewContainerRef, private templateRef: TemplateRef<any>) {}

  updateView() {
    this.vcRef.clear();
    this.vcRef.createEmbeddedView(this.templateRef, this.context);
  }
}

并像这样使用它:

<ng-template [ngVar]="true" let-x="ngVar"><div>{{x}}</div></ng-template>

<div *ngVar="true as x">{{x}}</div>

有什么魔力?

如果您想了解编译器的神奇之处,那么让我们看一个示例:

<div *ngVar="true as x"></div>

1) Angular 编译器将这个字符串标记为:

<div *ngVar="true as x"></div>
 (1)   (2)      (3)   (4) (5)


(1) - TAG_OPEN_START
(2) - ATTR_NAME
(3) - ATTR_VALUE
(4) - TAG_OPEN_END
(5) - TAG_CLOSE

2) HtmlParser 基于这些标记创建元素的树:

Element div
       attrs: name:  *ngIf
              value: true as x

3) TemplateParser 构建AST(抽象语法节点)树。为此,TemplateParser 使用名为 TemplateParseVisitor 的特殊访问者

此访问者遍历上一步中收到的所有树。让我们看看当编译器遇到 visitElement 时它是如何工作的:

enter image description here

因此我们可以看到任何带有结构指令的模板,例如:

*dir="someValue as someVar"

代表以下内容:

<ng-template [dir]="someValue" let-someVar="dir">

另见:

关于angular - Angular 在哪里为 *ngIf 定义 "as local-var"行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46616334/

相关文章:

javascript - Angular 4访问嵌套 react 表单元素

Angular2 - http.post(...).map 不是函数

javascript - 嵌套 Observables 在 Ionic2/Angular2 应用程序中表现不同

javascript - 如何在 Angular 中编写单个 post 服务并动态调用它多次?

android - 在下载 Android 源代码时,我得到的只是一堆空文件夹

javascript - Angular 8 *ngFor 中 HTML 输入中的数据绑定(bind)

asp.net - 类型错误 : Cannot read property of Selector-Matcher

open-source - Github:是否可以向所有观看项目的人发送消息?

linux - E文本编辑器git开源!!! linux下如何编译?

css - 是否可以隐藏 Primeng 日历中的输入字段?