Angulars结构指令的确切语法是什么 [英] What is the exact grammar for Angulars structural directives

查看:62
本文介绍了Angulars结构指令的确切语法是什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Angulars 文档解释说,结构指令,例如<p *ngIf="a as b"></p>是删除"到<p [ngIf]="a" [ngIfAs]="b">.

Angulars documentation explains, that structural directives, such as <p *ngIf="a as b"></p> are "desugared" into <p [ngIf]="a" [ngIfAs]="b">.

删除修饰符使用microsyntax,允许使用

The desugaring makes use of the microsyntax, that allows for expressions like

let node; when: hasChild
a as b
let x of y; index = i; trackBy: f

文档提供了一些微语法的示例,并建议研究ngIf的来源,但未提供正式定义.

The documentation provides some examples of the microsyntax, and suggest studying the sources of ngIf, but it provides no formal definition.

angular的结构指令的微语法是什么语法?

推荐答案

特殊部分Angular文档中的结构性指令语法.

您可以查看我的 交互式演示

You can check out my interactive DEMO

那么,这里的逻辑是什么?

So, what's the logic here?

一旦Angular遇到结构指令,它就会尝试解析它:

Once Angular meets structural directive it tries to parse it:

 *dir="..."
/\
indicates that it's a structural directive

一开始有3种情况:

*dir="expr
       \/
   [dir]="expr"

*dir="let var  // also var can have value
       \/ // starts with keyword 'let', indicates variable
   [dir] let-x="$impicit"


*dir="as var
      \/ // starts with keyword 'as'
  let-x="$impicit" // it won't fail but your directive won't be instantiated
      

在表达式之后,您可以使用 as关键字为该表达式定义模板输入变量,也可以使用诸如空格,冒号,分号或逗号之类的分隔符:

After an expression you can use either as keyword to define template input variable for that expression or a separator such as whitespace, colon, semicolon or comma:

*dir="expr as var
 \/
[dir]="exp" let-var="dir"

*dir="expr[ ]
*dir="expr:
*dir="expr;
*dir="expr,

请注意,此处将dir视为第一个模板绑定键.

Note that dir is considered here as the first template binding key.

现在该到另一个键或变量了:

Now it's time to another key or variable:

*dir="expr key2
*dir="expr:key2
*dir="expr;key2
*dir="expr,key2

我们可以通过空格或分号为该键分配值:

And we can assign value to that key through whitespace or semicolon:

*dir="expr key2 exp2
*dir="expr:key2 exp2
*dir="expr;key2 exp2
*dir="expr,key2 exp2
or
*dir="expr key2:exp2

这样,我们可以产生其他密钥.这些密钥大写并与第一个密钥连接.

And this way we can produce other keys. These key are capitalized and concatenated with the first key.

*dir="expr key2 exp2 key3 exp3 ...
\/
[dir]="expr " [dirKey2]="exp2 " [dirKey3]="exp3"


let node; when: hasChild; otherKey: otherValue
  \/       \/      \/
  var     key    value
                         \/
dir [dirWhen]="hasChild" [dirOtherKey]="otherValue" let-node="$implicit"


*dir="let x of y; index = i; trackBy: f"
           \/
dir [dirOf]="y" [dirIndex]="= i" [dirTrackBy]="f" let-x="$implicit"

*dir="let x  of   y;  let index = i; trackBy: f"
        \/   \/   \/      \/           \/    \/
        var  key  value     var          key   value
                   \/
dir [dirOf]="y" [dirTrackBy]="f" let-x="$implicit" let-index="i"
               

如您所见,我们可以定义键值或设置模板输入变量let或作为keywords

As you can see we can either define key-value or set template input variables through let or as keywords

如果您认为Angular文档没有完全解释它,则可以遵循

If you think that Angular docs doesn't completely explain it then you can follow the source code

  // Parses the AST for `<some-tag *tplKey=AST>`
  parseTemplateBindings(tplKey: string): TemplateBindingParseResult {
    let firstBinding = true;
    const bindings: TemplateBinding[] = [];
    const warnings: string[] = [];
    do {
      const start = this.inputIndex;
      let rawKey: string;
      let key: string;
      let isVar: boolean = false;
      if (firstBinding) {
        rawKey = key = tplKey;
        firstBinding = false;
      } else {
        isVar = this.peekKeywordLet();
        if (isVar) this.advance();
        rawKey = this.expectTemplateBindingKey();
        key = isVar ? rawKey : tplKey + rawKey[0].toUpperCase() + rawKey.substring(1);
        this.optionalCharacter(chars.$COLON);
      }

      let name: string = null !;
      let expression: ASTWithSource|null = null;
      if (isVar) {
        if (this.optionalOperator('=')) {
          name = this.expectTemplateBindingKey();
        } else {
          name = '\$implicit';
        }
      } else if (this.peekKeywordAs()) {
        this.advance();  // consume `as`
        name = rawKey;
        key = this.expectTemplateBindingKey();  // read local var name
        isVar = true;
      } else if (this.next !== EOF && !this.peekKeywordLet()) {
        const start = this.inputIndex;
        const ast = this.parsePipe();
        const source = this.input.substring(start - this.offset, this.inputIndex - this.offset);
        expression = new ASTWithSource(ast, source, this.location, this.errors);
      }

      bindings.push(new TemplateBinding(this.span(start), key, isVar, name, expression));
      if (this.peekKeywordAs() && !isVar) {
        const letStart = this.inputIndex;
        this.advance();                                   // consume `as`
        const letName = this.expectTemplateBindingKey();  // read local var name
        bindings.push(new TemplateBinding(this.span(letStart), letName, true, key, null !));
      }
      if (!this.optionalCharacter(chars.$SEMICOLON)) {
        this.optionalCharacter(chars.$COMMA);
      }
    } while (this.index < this.tokens.length);

    return new TemplateBindingParseResult(bindings, warnings, this.errors);
}

上面的代码描述了如何解析结构指令的算法.

The code above describes the algorithm of how a structural directive is parsed.

另请参见

这篇关于Angulars结构指令的确切语法是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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