# 了解绑定

在 Angular 模板中,绑定会在从模板创建的一部分 UI(DOM 元素、指令或组件)与模型(模板所属的组件实例)之间创建实时连接。此连接可用于将视图与模型同步、在视图中发生事件或用户操作时通知模型,或两者兼而有之。Angular 的变更检测算法负责保持视图和模型的同步。

绑定的例子包括:

  • 文本插值

  • 属性绑定

  • 事件绑定

  • 双向绑定

绑定始终有两部分:将接收绑定值的目标和从模型生成值的模板表达式。

# 语法

模板表达式类似于 JavaScript 表达式。许多 JavaScript 表达式都是合法的模板表达式,但以下例外。

你不能使用那些具有或可能引发副作用的 JavaScript 表达式,包括:

  • 赋值 (=, +=, -=, ...)

  • 运算符,比如 newtypeofinstanceof等。

  • 链接表达式;

  • 自增和自减运算符:++--

  • 一些 ES2015+ 版本的运算符

和 JavaScript 语法的其它显著差异包括:

  • 不支持位运算,比如 |&

  • 新的模板表达式运算符,比如 |

# 表达式上下文

插值表达式具有上下文 —— 表达式所属应用中的特定部分。通常,此上下文就是组件实例。

在下面的代码片段中,表达式 recommendeditemImageUrl2表达式所引用的都是 AppComponent中的属性。

src/app/app.component.html

<h4>{{recommended}}</h4>
<img alt="item 2" `src]="itemImageUrl2">

表达式还可以引用模板上下文中的属性,比如模板输入变量` 或[模板引用变量。

下面的例子就使用了模板输入变量 customer

src/app/app.component.html (template input variable)

<ul>
  <li *ngFor="let customer of customers">{{customer.name}}</li>
</ul>

接下来的例子使用了模板引用变量 #customerInput

src/app/app.component.html (template reference variable)

<label>Type something:
  <input #customerInput>{{customerInput.value}}
</label>

TIP

模板表达式不能引用全局命名空间中的任何东西,除了 undefined。他们不能引用 windowdocument。此外,它们不能调用 console.log()Math.max(),并且只能引用表达式上下文的成员。

# 防止命名冲突

表达式估算的上下文是模板变量、指令的上下文对象(如果有)和组件成员的并集。如果你引用的名称属于这些命名空间之一,则 Angular 会应用以下优先逻辑来确定上下文:

  • 模板变量的名称。

  • 指令上下文中的名称。

  • 组件成员的名称。

为避免变量遮盖另一个上下文中的变量,请保持变量名称唯一。在以下示例中,AppComponent模板在问候 customerPadma。

然后,一个 ngFor列出了 customers数组中的每个 customer

src/app/app.component.ts

@Component({
  template: `
    <div>
      <!-- Hello, Padma -->
      <h1>Hello, {{customer}}</h1>
      <ul>
        <!-- Ebony and Chiho in a list-->
        <li *ngFor="let customer of customers">{{ customer.value }}</li>
      </ul>
    </div>
  `
})
class AppComponent {
  customers = [{value: 'Ebony'}, {value: 'Chiho'}];
  customer = 'Padma';
}

ngFor中的 customer处于一个 &lt;ng-template&gt;的上下文中,所以它指向的是 customers数组中的 customer,在这里是 Ebony 和 Chiho。此列表中不包含 Padma,因为那个 customer位于 ngFor以外的另一个上下文中。反之,&lt;h1&gt;中的 customer不包括 Ebony 或 Chiho,因为该 customer的上下文是组件类,而这个类中 customer的值是 Padma。

# 表达式最佳实践

使用模板表达式时,请遵循以下最佳实践:

  • 使用短表达式

尽可能使用属性名称或方法调用。将应用和业务逻辑保留在组件中,这里更便于开发和测试。

  • 快速执行

Angular 会在每个变更检测周期之后执行一个模板表达式。许多异步活动会触发变更检测周期,比如 promise 解析、HTTP 结果、计时器事件、按键和鼠标移动。

表达式应该快速完成,以保持用户体验尽可能高效,在较慢的设备上尤为明显。当计算需要更多资源时,考虑缓存值。

# 没有明显的副作用

根据 Angular 的单向数据流模型,除了目标属性的值之外,模板表达式不应更改任何应用状态。读取组件值不应更改其他显示值。该视图应在整个渲染过程中保持稳定。

用幂等表达式减少副作用Idempotent expressions reduce side effects幂等 的表达式是最理想的,因为它没有副作用,并且可以提高 Angular 的变更检测性能。用 Angular 术语来说,幂等表达式总会返回完全相同的东西,除非其依赖值之一发生了变化。

在单独的一次事件循环中,被依赖的值不应该改变。如果幂等的表达式返回一个字符串或数字,如果连续调用它两次,会返回相同的字符串或数字。如果幂等的表达式返回一个对象(也包括 Array),如果连续调用它两次,会返回同一个对象的引用。

# 下一步呢?

  • property 绑定

  • 事件绑定

Last Updated: 5/13/2023, 10:57:08 AM