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

When to use square brackets [ ] in directives @Inputs and when not?

有点迷糊

查看这个简单的指令:

 @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 的用户永远不需要怀疑是否,我认为方括号 [] 应该始终存在。不是吗?

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

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

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

[myEnabled]="true" 起作用的原因是因为 true 是一个有效的模板表达式,它的计算结果当然是布尔值 true.

括号告诉 Angular 计算模板表达式。如果省略括号,Angular 会将字符串视为常量并使用该字符串初始化目标 属性。它不计算字符串!

不要犯以下错误:

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

binding [] 用于对象,没有它值为字符串。小心类型。

代码中

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

您已尝试绑定该对象,但该对象不可用,因此它的值为undefined。另一方面,如果您删除绑定,那么该对象就会消失,您只有一个 string 值分配给 属性.

如果写成<img [src]="heroImageUrl">就表示右边heroImageUrl是一个模板表达式。

[myText]="abc"myText="abc" 之间的简单区别在于,在前者中,您要求 angular 使用模板表达式 abc 设置目标 属性 myText ],而在后者中,您使用字符串 'abc'.

设置名为 myText 的目标 属性

让我们进一步了解 HTML。

在HTML中你可以这样定义一个元素。

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

input 是一个元素,其 attributes 是类型和值。当你的浏览器解析它时,它会为这个元素创建一个 DOM 条目(一个对象)。 DOM 条目将有一些 properties,如 align、baseURI、childNodes、children 等。因此,这就是 HTML 属性和 DOM 属性 See reference 之间的区别。有时属性和 属性 具有相同的名称,这会导致混淆。对于上面的输入标记,它具有属性 value = Bob 并且还有一个 属性 value ,它将具有您在文本框中键入的任何值。总之,属性是您定义的标签,属性 是在 DOM 树中生成的内容。

在Angular的世界里,属性的唯一作用是初始化元素和可能的指令状态。编写数据绑定时,您专门处理目标对象的属性和事件。 HTML 属性有效消失。

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

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

来自Angular guide on property binding

The brackets, [], cause Angular to evaluate the right-hand side of the assignment as a dynamic expression. Without the brackets, Angular treats the right-hand side as a string literal and sets the property to that static value.

这是 Angular13 的最新更新。

举个例子...

假设我们有一个名为 carImage 的输入变量,它将包含从父级传递的动态 URL 值。

@Input() carImage = '';

场景1 - 带方括号

<img [src]="carImage"></img>

在这种情况下,无论 carImage 变量持有什么值,都将分配给 imgsrc 属性。这是 property binding,我们可以在其中动态设置属性值。

场景 2 - 没有方括号

<img src="carImage"></img>

在这种情况下,字符串 carImage 将直接分配给 src 属性,因此 Angular 将无法显示图像,因为它是无效的 URL.

要使其工作,您必须分配一个有效的URL,如下所示。

<img src="http://demo/carImage.jpg"></img>