关于插值表达式和属性绑定的一点总结

Ng 项目中插值表达式和属性绑定随处可见,两者都是单向数据绑定,将数据呈现在视图层。

Ng 会将插值表达式转换为属性绑定。因此在有些场景中,插值表达式和属性绑定的表现效果一致。

import { Component } from '@angular/core';

@Component({
    selector: 'my-app',
    template: `<div>
                    <h1>{{title}}</h1>
                    <img src='{{imageSrc}}'/>
                </div>`
})
export class AppComponent {
    title: string = '插值表达式';
    imageSrc: string = 'https://example.com/demo.jpg';
}

import { Component } from '@angular/core';

@Component({
    selector: 'my-app',
    template: `<div>
                    <h1 [innerHTML]='title'></h1>
                    <img [src]='imageSrc'/>
                </div>`
})
export class AppComponent {
    title: string = '属性绑定';
    imageSrc: string = 'https://example.com/demo.jpg';
}

但是,在以下几方面,插值表达式和属性绑定有所区别:

  • 数据类型
    如果绑定的数据是 String 类型,那么两者皆可;如果绑定的数据类型为 Object,那么必须使用属性绑定

    import { Component } from '@angular/core';
    
    @Component({
      selector: 'my-app',
      template: `<hello name="{{ng}}"></hello>
                <hello [name]="ng"></hello>`,
      styleUrls: ['./app.component.css']
    })
    export class AppComponent {
      name = 'Angular';
    
      ng = { name: 'Angular' }
    }
    import { Component, Input, OnInit } from '@angular/core';
    
    @Component({
      selector: 'hello',
      template: `<h1>Hello {{name}}!</h1>`,
      styles: [`h1 { font-family: Lato; }`]
    })
    export class HelloComponent implements OnInit {
      @Input() name: Object;
    
      ngOnInit() {
        console.info(this.name);
      }
    }
  • 插值表达式支持字符串拼接等 JS 运算操作,属性绑定不支持

    <img [src]="src" alt="">
    
    <img src="{{ 'http://exmaple.com/' + src}}" alt="">
  • 插值表达式初始化的是 attribute,而属性绑定是与元素的 property 打交道

上面 Demo 中,分别通过插值表达式和属性绑定设置按钮禁用状态,通过 Change Status 按钮切换禁用状态。通过实践发现,切换 disabled 为 false 时,通过插值表达式设置禁用状态的按钮仍为禁用状态,而属性绑定的按钮已恢复为正常状态。
对于这一现象,本质上是 attribute 与 property 的区别。对于 Boolean 类型的 attribute,attribute 只是初始化 DOM 状态,之后通过 attribute 方式修改 DOM 状态无法生效,只有通过 property 方式才能生效。在 Ng 中,attribute 唯一的作用是用来初始化元素和指令的状态。当进行数据绑定时,只是在与元素和指令的 property 和事件打交道。