何时在指令@Inputs中使用方括号[],何时不使用?

时间:2017-04-26 11:53:04

标签: angular typescript angular2-directives

我有点困惑。

请参阅此简单指令:

 @Directive({
      selector: '[myDirective]'
    })
    export class MyDirective {

      private text: string;
      private enabled: boolean;

      @Input() myDirective:string;

      @Input('myText')
      set myText(val: string) {
        this.text = val;
      }

      @Input('myEnabled')
      set myEnabled(val: boolean) {
        this.enabled = val;
      }

      ngOnInit() {

        console.log("myDirective string: " + this.myDirective);
        console.log("myText string: " + this.text); 
        console.log("myEnabled boolean: " + this.enabled);
    }
}

如果我的html看起来像这样:

<div [myDirective]="myDefaultText" [myEnabled]="true"  [myText]="abc"></div>

输出将是:

myDirective string: myDefaultText real value  // good
myEnabled boolean: true                       // good
myText string: undefined                      // Why?

如果我从myText删除[]:

<div [myDirective]="myDefaultText" [myEnabled]="true"  myText="abc"></div>

输出将是:

myDirective string: myDefaultText real value  // good
myEnabled boolean: true                       // good
myText string: abc                            // GOOD

我也可以从[]删除myEnabled,它也会有用。 所以这是我的困惑 - 当我需要使用方括号[]时,如果没有,我希望将要使用myDirective的用户永远不需要怀疑是否,如果没有,我认为方括号[]应始终存在。不是吗?

5 个答案:

答案 0 :(得分:22)

当您使用[]绑定到@Input()时,它基本上是一个模板表达式。

显示{{abc}}的方式相同,不会显示任何内容(除非您实际上有一个名为abc的变量)。

如果你有一个字符串@Input(),并且你想将它绑定到一个常量字符串,你可以像这样绑定它:[myText]=" 'some text' ",或者简而言之,就像普通的HTML属性一样:{{ 1}}。

myText="some text"工作的原因是因为[myEnabled]="true"是一个有效的模板表达式,当然它的结果是布尔值true

答案 1 :(得分:9)

括号告诉Angular评估模板表达式。如果省略括号,Angular会将字符串视为常量,并使用该字符串初始化target属性。它没有评估字符串!

不要犯下以下错误:

    <!-- ERROR: HeroDetailComponent.hero expects a
         Hero object, not the string "currentHero" -->
    <hero-detail hero="currentHero"></hero-detail>

检查:https://angular.io/docs/ts/latest/guide/template-syntax.html#!#property-binding

答案 2 :(得分:5)

绑定[]用于对象,没有它,值为string。关注类型。

在代码中

<div [myDirective]="myDefaultText" [myEnabled]="true"  [myText]="abc"></div>

您尝试绑定对象,但该对象不可用,因此它的值为undefined。另一方面,如果删除绑定,则对象消失,您只为该属性分配了string值。

答案 3 :(得分:2)

我想我理解您的困惑来自何处。当您说[myText]="abc"时,您期望myText是在我的组件中定义的属性,我想将其值初始化为abc。但这是不正确的。但是首先,让我们进一步了解HTML。

在HTML中,您可以定义这样的元素。

<input type="text" value="Bob">

input是一个元素,其attributes是类型和值。当您的浏览器对此进行解析时,它将为此元素创建一个DOM条目(一个对象)。 DOM条目将具有一些properties,例如align,baseURI,childNodes,children等。因此,这就是HTML属性和DOM属性See reference之间的区别。

之所以需要知道这一点,是因为在Angular的世界中,属性的唯一作用是初始化元素和指令状态。编写数据绑定时,您仅在处理目标对象的属性和事件。 HTML属性有效消失。

这意味着,如果您编写<img [src]="heroImageUrl">,则意味着src不是属性,而是在img的DOM内定义的property。右侧heroImageUrl是模板表达式。

[myText]="abc"myText="abc"之间的简单区别是,在前者中,您要向angular设置PROPERTY myText,在后者中,您要创建一个名为myText的ATTRIBUTE,该属性将具有自己的属性DOM属性。 Angular不处理属性。

总而言之,在<div [myDirective]="myDefaultText" [myEnabled]="true" [myText]="abc"></div>中,您实际上是在说:

  1. 将指令myDirective应用于我的div元素。
  2. 将变量myEnabled绑定到右侧的表达式。表达式显示为true,因此myEnabled的值为true。
  3. 将变量myText绑定到右侧的表达式。表达式为abc。是否定义了abc?否,因此表达式的计算结果为undefined。

答案 4 :(得分:0)

来自Angular guide on property binding

<块引用>

括号 [] 使 Angular 将赋值的右侧评估为动态表达式。如果没有括号,Angular 会将右侧视为字符串文字并将属性设置为该静态值。