# Day09 【牙起來】 繫結3 屬性綁定 - 程式面介紹
以下三張圖分別代表 **小劍**、**彎刀**、**大魔劍** 三種武器
(圖片源自unsplash)
我們把這些圖示放入遊戲專案中
**小劍**

**彎刀**

**大魔劍** (圖片找得太尖細了...

在Angular專案架構中,會把這些照片等資源都放入`\src\assets` 底下
在這裡新建一個 `image` 資料夾

> 這邊的 `.gitkeep` 可以用力刪除
> 因為git不會控管**空資料夾**,所以創一個檔案`.gitkeep`給git看
> 這資料夾底下有東西所以請控管他,用途僅此
然後把三張圖片放入到此資料夾中

## 原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>
```

但是這樣每張照片都一樣,照片每一把都是**小劍**,沒辦法達成預期
所以接下來要做的就是讓程式去控制要顯示的圖片
## 屬性繫結 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**
這樣就大功告成啦~
完成畫面

### 將圖片路徑寫在物件內
刪除 `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>
```
### 將圖片名稱以數字編號
若圖片檔名改以數字流水號來命名

要取用時只需使用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>
```
若對這一串還不是很了解的話
可以將兜出來的字串(圖片路徑),透過繫結綁定印出來看看

---
### 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**屬性值
這部分用法未來會再提及

> 到這一步 恭喜你,已經學會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'">
```

結果可以看到 `attribute` 的值與 `property` 的值相同
等於`attribute`被屬性繫節的值覆蓋了
### 不過也有例外
來看一個例子
在HTML上只留下 `<input>` 以及 預設值 `value` **勇者一號**
```html=
<input type="text" value="勇者一號">
```
輸入框在被修改之前,`Attribute` 與 `Property` 都是 **勇者一號**

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

此時 `Property` 為**砲灰一號**,但`Attribute` 仍是**勇者一號**
使用屬性繫節也會得到相同結果
```html=
<input type="text" value="勇者一號" [value]="'勇者一號'">
```
這裡只能透過Javascript的 `setAttribute()` 手段來修改HTML Attribute