Angular 4 在哪里定义“作为本地变量"?*ngIf 的行为? [英] Where does Angular 4 define "as local-var" behavior for *ngIf?

查看:16
本文介绍了Angular 4 在哪里定义“作为本地变量"?*ngIf 的行为?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

尝试查看源代码中的明显位置,例如

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

*dir="someValue as someVar"

代表以下内容:

另见:

I am trying to understand where is the "as local-var" optional behavior of ngIf defined, e.g.: *ngIf="user$ | async as user"

Tried looking into obvious places in source, like https://github.com/angular/angular/blob/master/packages/common/src/directives/ng_if.ts

But nothing in the code, only docs.

Does anyone know where in the code this magic is happening ?

解决方案

Yeah, it's magic that happens during template compilation.

The template below

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

is just sugar for:

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

So the answer: the following string passes value to this variable:

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

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

For example we can create structural directive 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);
  }
}

and use it either like:

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

or

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


What's the magic?

If you want to understand where is the magic in compiler then let's take a look at an example:

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

1) Angular compiler tokenizes this string like:

<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 creates element's tree based on these tokens:

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

3) TemplateParser builds AST(abstract syntax node) tree. To do this TemplateParser uses special visitor called TemplateParseVisitor

This visitor goes through all tree received in the previous step. And let's look at how it works when compiler comes to visitElement:

So as we can see any template with structural directive like:

*dir="someValue as someVar"

represents the following:

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

See also:

这篇关于Angular 4 在哪里定义“作为本地变量"?*ngIf 的行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆