新新新手阅读 Angular 文件 - DataBinding - Day17

本文内容

学习在 Angular 中 Data Binding 的机制。

Data Binding 四种方式

Angular 提供了四种 Data Binding 的方式,他们的不同除了写法上的不同,最主要是它们资料传递方向的不同。
有的是资料从元件传到 DOM、有的是资料从 DOM 传到元件、有的资料是可以在元件和 DOM 之间双向传递。

1. Interpolation - 资料从元件传递到 DOM
这个在前几天的文章中有提到过了,主要是用来将元件的资料呈现在 DOM 上,我们会用要被呈现在 DOM 上的属性名称用双花括 (curly braces) 把它包起来。

--- app.component.ts ---
export class AppComponent {
  name = 'Jasper';
}

--- app.component.html ---
<p> {{ name }} </p>

以上的范例,就可以将元件的 name 成员属性内容插入到 p 段落里面。

2. Property binding - 资料由元件流向指定 DOM 的属性上
我们会利用这种方式,来将元件定义的成员属性绑定到指定的 DOM 属性上。

--- app.component.ts ---
export class AppComponent {
  title = 'Jasper';
}

--- app.component.html ---
<input type="text" [placeholder]="title"> 

以上范例可以看到,我们把被指定 DOM 的属性用中括号 (brackets) 把它包起来,并将元件的属性绑定它到身上。
所以,以上的范例的结果就会像下面这样
https://ithelp.ithome.com.tw/upload/images/20210917/20140093qhK0irdS9S.png

3. Event binding - 资料流方向为从 DOM 流向元件
这个情境就是,当你点击画面上的某个按钮时,会触发这个按钮的 click 事件,而这个 click 事件会再触发到元件定义的某个函式,这个触发的机制就是资料流方向为从 DOM 流向元件。

--- app.component.html ---
<input #target (input)="search(target.value)">

--- app.component.ts ---
search(res) {
  console.log(res);
}

以上的范例,就是当在 input 栏位输入内容的时候,就会触发到它的 input 事件,而它的 input 事件又会去触发到元件定义的 search 函式,并同时把输入的内容传入进去,操作的结果会像下面这样

4. Two-way data binding - 资料流会在元件和 DOM 之间传递
这个就是着名的双向绑定~~
当你在 DOM 修改其内容的时候,也会连带的修改到元件对应的属性内容,反之,更改元件的属性内容,就会连带地修改到 DOM 的对应内容。

--- app.component.ts ---
title = 'Jasper'

--- app.component.html ---
<input type="text" [(ngModel)]="title">

以上这个范例会将该 input 栏位的 value 属性值与元件的 title 属性作双向绑定。

Note:
在 Angular 中,在 input 或 textarea 使用 [(ngModel)] 的话,就会自动将这个双向绑定的效果加到他们的 value 属性上喔。

简单的计算机范例

这边做一个极度简陋的计算机,来练习一下,上面提到的 Event binding 和 Property binding 这两个 data-binding 的功能。
首先,是 html 的部分

<div>
  <span>计算结果: </span>
  <input type="text" [value]="currentProgress" />
  <p>
    <button type="button" (click)="getFirstNumber(3)">3</button>
    <button type="button" (click)="getSecondtNumber(5)">5</button>
  </p>

  <p>
    <button type="button" (click)="getOperation('+')" class="operator">
      +
    </button>

    <button type="button" (click)="getOperation('=')">=</button>
  </p>
  
  <p>
    <button (click)="clear()">Clear</button>
  </p>
</div>
  1. 在上面的 input 栏位,有看到我们用 Property binding 的方式,把它的 value 跟元件的 currentProgress 属性绑定在一起,用以呈现使用者按下的内容。
  2. 在各个 button 按钮上,可以看到都有使用 Event binding 的方式绑定它的 click 事件,进而去触发相对应的元件函式,并传入该按钮的内容。

接下来,就是写这些函式和属性的内容,他们会写在该元件的 ts 档案中

export class AppComponent {
  firstNumber = null;
  secondNumber = null;
  currentProgress = '';

  getFirstNumber(first: number) {
    this.firstNumber = first;
    this.currentProgress += stringify(this.firstNumber);
  }

  getSecondtNumber(second: number) {
    this.secondNumber = second;
    this.currentProgress += stringify(this.secondNumber);
  }

  getOperation(op: string) {
    switch (op) {
      case '+':
        this.currentProgress += '+';
        return this.firstNumber;
      case '=':
        const result = this.firstNumber + this.secondNumber;
        this.currentProgress = this.currentProgress + '=' + stringify(result);
        return this.firstNumber;
    }
  }
  
  clear() {
    this.firstNumber = null;
    this.secondNumber = null;
    this.currentProgress = '';
  }
}

上面的内容蛮单纯的,就是将传入的数字分别设给 firstNumber 和 secondNumber,并将它们转型成字串设入 currentProgress 中,也因为我们有为 input 栏位的 value 属性绑上 currentProgress 的属性,所以,currentProgress 当下的内容就会即时被呈现在 input 栏位中罗~

操作结果如下

Summary

这边做个总结

  1. Angular 有提供四种 Data Binding 的方式,除了要注意它们写法上的不同,还要注意它们彼此之间资料流的方向。

Note:
这边想要特别注明一下,这四种 Data Binding 的方式,只有 interpolation 的时候,也就是想要直接将元件的属性内容呈现在画面上才会需要将属性用双花括把它包起来,另外三种就直接写上属性名称就好,不要搞错了,我自己是很常搞混啦....XD


<<:  第1砍 - 磨刀霍霍

>>:  [Day 16] 针对网页的单元测试(二)

【左京淳的JAVA WEB学习笔记】第十一章 显示列表、图片、商品细节

显示列表 访问案例网站时默认调用index.jsp,在此页面设定转向MainSvl。 http://...

[神经机器翻译理论与实作] 重新检视有无注意力机制的Encoder-Decoder

前言 今天是个美丽的错误,本来预计将昨日写好的 Encoder 、Decoder 、 LuongAt...

Day 10 - Rancher 丛集管理指南 - RKE 管理与操作

本文将於赛後同步刊登於笔者部落格 有兴趣学习更多 Kubernetes/DevOps/Linux 相...

进击的软件工程师之路-软件战斗营 第十六周

学习进度 通识 GCP架设 Android Studio Spinner使用(自学) Date、Ti...

Day 22.5 | Livewire 实作 购物网站: 建立资料表

本来预计都写在 Day22 的,但是加上本篇内容後会让一天的篇幅太长,且考虑到有些夥伴可能没有建立资...