---
# System prepended metadata

title: Day09 【牙起來】 繫結3 屬性綁定 - 程式面介紹

---

# Day09 【牙起來】 繫結3 屬性綁定 - 程式面介紹

以下三張圖分別代表 **小劍**、**彎刀**、**大魔劍**　三種武器
（圖片源自unsplash）

我們把這些圖示放入遊戲專案中

**小劍**
![小劍](https://i.imgur.com/R5lchoc.jpg)

**彎刀**
![彎刀](https://i.imgur.com/rIjafZZ.jpg)

**大魔劍** (圖片找得太尖細了...
![魔劍](https://i.imgur.com/A1DHORH.jpg)


在Angular專案架構中，會把這些照片等資源都放入`\src\assets` 底下

在這裡新建一個 `image` 資料夾

![](https://i.imgur.com/PDdx6vG.png)

> 這邊的 `.gitkeep` 可以用力刪除
> 因為git不會控管**空資料夾**，所以創一個檔案`.gitkeep`給git看
> 這資料夾底下有東西所以請控管他，用途僅此

然後把三張圖片放入到此資料夾中
![](https://i.imgur.com/oW1aPrf.png)



## 原Html img引用圖片方法

透過原生的HTML引用圖片的方法
把 `<img src="...">` 放入For迴圈中，讓圖片循環的產生
同時為了避免超出邊界框，限制圖片高度 `height="150"`

修改 `store.component.html`

```html=
<h2>商店區塊</h2>
<div *ngFor="let weapon of weapons; let i = index">
  <div>武器編號: {{i + 1}}</div>
  <div>武器名稱: {{weapon.name}}</div>
  <div *ngIf="weapon.atk">武器攻擊力: {{weapon['atk']}}</div>
  <img src="assets/image/小劍.jpg" height="150" alt="武器">
  <br><br>
</div>
```

![](https://i.imgur.com/HZknIrI.png)


但是這樣每張照片都一樣，照片每一把都是**小劍**，沒辦法達成預期
所以接下來要做的就是讓程式去控制要顯示的圖片

## 屬性繫結 property binding

在程式內先寫好每把武器對應的圖片路徑

新建一個陣列 `imgSources`，依序存放圖片路徑 `['assets/image/小劍.jpg', 'assets/image/彎刀.jpg', 'assets/image/大魔劍.jpg']`

修改 `store.component.ts`

```typescript=
...

export class StoreComponent implements OnInit {

  weapons = [
    {name: '小劍', atk: '5'},
    {name: '彎刀', atk: '7'},
    {name: '大魔劍', atk: '11'}
  ];

  imgSources = ['assets/image/小劍.jpg', 'assets/image/彎刀.jpg', 'assets/image/大魔劍.jpg']

  constructor() { }

  ngOnInit(): void {
  }
}
```

接著使用 **屬性繫結** `[src]`

將程式陣列變數 與 圖片位置`src`做綁定
透過index來索引圖片陣列，顯示出第 `i` 個路徑的圖片位置

修改 `store.component.html`

```html=
<h2>商店區塊</h2>
<div *ngFor="let weapon of weapons; let i = index">
  <div>武器編號: {{i + 1}}</div>
  <div>武器名稱: {{weapon.name}}</div>
  <div *ngIf="weapon.atk">武器攻擊力: {{weapon['atk']}}</div>
  <img [src]="imgSources[i]" height="150" alt="武器">
  <br><br>
</div>
```

被中括號`[]`包起來的attribute，就稱 **property**


這樣就大功告成啦~
完成畫面
![](https://i.imgur.com/BAgdKaB.png)

### 將圖片路徑寫在物件內

刪除 `imgSources` 陣列
改將圖片路徑寫在**Weapon物件**內，新增 `imgSrc` 屬性
這樣子的寫法也能達成相同效果

修改 `store.component.ts`

```typescript=
export class StoreComponent implements OnInit {

  weapons = [
    {name: '小劍', atk: '5', imgSrc: 'assets/image/小劍.jpg'},
    {name: '彎刀', atk: '7', imgSrc: 'assets/image/彎刀.jpg'},
    {name: '大魔劍', atk: '11', imgSrc: 'assets/image/大魔劍.jpg'}
  ];

  constructor() { }

  ngOnInit(): void {
  }
}
```

接著修改 `store.component.html`，用 `weapon.imgSrc` 取得物件內的圖片路徑

```html=
<h2>商店區塊</h2>
<div *ngFor="let weapon of weapons; let i = index">
  <div>武器編號: {{i + 1}}</div>
  <div>武器名稱: {{weapon.name}}</div>
  <div *ngIf="weapon.atk">武器攻擊力: {{weapon['atk']}}</div>
  <img [src]="weapon.imgSrc" height="150" alt="武器">
  <br><br>
</div>
```

### 將圖片名稱以數字編號

若圖片檔名改以數字流水號來命名

![](https://i.imgur.com/yDYYxer.png)

要取用時只需使用index `i` 的遞增特性
想辦法組合字串與變數，兜出檔案路徑名稱即可

將 `[src]` 修改為 `[src]="'assets/image/' + (i+1) +'.jpg'"`

修改 `store.component.html`

```html=
<h2>商店區塊</h2>
<div *ngFor="let weapon of weapons; let i = index">
  <div>武器編號: {{i + 1}}</div>
  <div>武器名稱: {{weapon.name}}</div>
  <div *ngIf="weapon.atk">武器攻擊力: {{weapon['atk']}}</div>
  <img [src]="'assets/image/' + (i+1) +'.jpg'" height="150" alt="武器">
  <div>圖片路徑: {{'assets/image/' + (i+1) +'.jpg'}}</div>
  <br><br>
</div>

```

若對這一串還不是很了解的話
可以將兜出來的字串（圖片路徑），透過繫結綁定印出來看看

![](https://i.imgur.com/Ys6ar5o.png)

---


### Attribute 與 Property 的差異

`Attribute` 與 `Property` 的中文都是**屬性**，這兩者有何差別？　

HTML上的 `attribute` 會被轉為對應的DOM
DOM上的各項數值的欄位稱為`property`

* `attribute` 指的是 在HTML上就有的屬性
`<img src="assets/image/小劍.jpg" height="150" alt="武器">`
例如`src`、`height`、`alt` 這些都是 **attribute**

* `property` 指的是 DOM上的元素
`<img [src]="'assets/image/小劍.jpg'" [height]="'150'" [alt]="'武器'">`
例如 `[src]`、`[height]`、`[alt]` 這些都是 **property**

Angular讓我們能對著既有的**HTML Attribute**
在外層加上殼`[]` 變成**Property**，就可以對`值`進行操作

另外，Angular也可以在自定義的標籤上，帶入自定義的**Property**屬性值
這部分用法未來會再提及

![](https://i.imgur.com/x1dlZKk.png)


> 到這一步 恭喜你，已經學會69%的 Angular
> 
> 以下部分不是非常重要，有興趣再看就好

---


### 大部分情況下，修改 `property` 時會連動影響 `attribute`

譬如在HTML樣板中這樣子玩 （~~開發時這樣玩會被打死~~）
同時有 `src` 又有 `[src]`、同時有 `height` 又有 `[height]`
並且兩邊都設定成不同數值

```html=
<img src="assets/image/1.jpg" [src]="'assets/image/3.jpg'"
     height="9999999" [height]="'150'">
```

![](https://i.imgur.com/6mIwk7P.png)

結果可以看到 `attribute` 的值與 `property` 的值相同
等於`attribute`被屬性繫節的值覆蓋了


### 不過也有例外

來看一個例子

在HTML上只留下 `<input>` 以及 預設值 `value` **勇者一號**

```html=
<input type="text" value="勇者一號">
```

輸入框在被修改之前，`Attribute` 與 `Property` 都是 **勇者一號**

![](https://i.imgur.com/a2NwwT4.png)

接著手動輸入文字，將**勇者一號**改為**砲灰一號**
修改輸入框之後在開發工具中重新點擊一次該DOM

![](https://i.imgur.com/MmhKTah.png)

此時 `Property` 為**砲灰一號**，但`Attribute` 仍是**勇者一號**

使用屬性繫節也會得到相同結果

```html=
<input type="text" value="勇者一號" [value]="'勇者一號'">
```

這裡只能透過Javascript的 `setAttribute()` 手段來修改HTML Attribute
