Component 介紹
===
---
## 10點~11點 Component 介紹
## [簡報網址](https://ppt.cc/fhrjnx)
## QRCODE 支援
<img src="http://s01.calm9.com/qrcode/2017-08/F2DV4FKUYG.png" >
---
<img src="http://imgur.com/ZB3mLiL.jpg" height="200" style="border:1px solid #fff">
主講者:拉拉 lala.lee
經歷:三竹資訊 前端工程師
<!-- .element: class="fragment" data-fragment-index="2" -->
[Angular線上讀書會](https://www.facebook.com/groups/angularstudygroup/) 成員
<!-- .element: class="fragment" data-fragment-index="3" -->
[Angular Girls Taiwan](https://www.facebook.com/groups/AngularGirlsTaiwan/) 社團負責人
<!-- .element: class="fragment" data-fragment-index="4" -->
---
## Component Intro
* 一個Angular專案基本上是由數個Component組成
* 一個Componet還可以包含很多個子Component
* Component各司其職,適當的彼此溝通
---
## 任務 07:介紹 Component
Componet = <span><!-- .element: class="fragment highlight-green" -->Import</span> + <span><!-- .element: class="fragment highlight-blue" -->Template & Metadata</span> + <span><!-- .element: class="fragment highlight-red" -->Class</span>
![](https://i.imgur.com/3o3gwD6.png)
----
## Component - Import
![](https://i.imgur.com/A5YHAmB.png)
----
## Component - Metadata(1)
```typescript
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app works!';
}
```
* ES6的Decorator語法
* 使用@Component({...})將class"裝飾"成元件
* {...} 用來讓Angular核心知道如何建構元件
----
## Component - Metadata(2)
```typescript
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app works!';
}
```
* basic metadata => selector + template + style
* selector: 哪個HTML element要套用此元件
* templateUrl: 此元件的 模版 位置
* styleUrls: 此元件的 樣式檔案 位置
----
## Component - Template
![](https://i.imgur.com/Oq8WNGE.png)
Inline的優點是只需一個檔案就能完成Component
缺點是沒有Intellisense 容易出錯,建議使用Linked
----
## Component - Class (1)
```typescript
@Component({
// ...
})
export class AppComponent {
title:string = 'app works!';
clickTitle() { ... }
}
```
* 類別名稱,使用Pascal命名法
* 最好加上Component字眼,標示其為元件
* 加上 export 關鍵字,可讓其他程式使用
----
## Component - Class (2)
```typescript
@Component({
// ...
})
export class AppComponent {
appTitle:string = 'app works!'; // data in class property
clickTitle() { ... } // login in class method
}
```
* property、method 使用 Lower Camel Casing
* property 定義資料模型,並設定型別及初始值
* method 封裝程式邏輯
---
## TodoApp 架構
![](https://i.imgur.com/L4x0xsb.png)
---
### 任務 7-1:內嵌繫結 (Interpolation)
* 將 app.component.ts 中的 title 屬性移到 title.component.ts 檔案中
* 透過 內嵌繫結 (Interpolation) 將 title 屬性顯示在 Template 的 h1 標籤內
* 內嵌繫結語法:```{{variable}}```
----
### Header Component - Interpolation (1)
header.component.html
```htmlembedded=
<h1>{{title}}</h1>
```
header.component.ts
```typescript=
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {
title:string = 'My Todos';
constructor() { }
ngOnInit() {}
}
```
----
### Header Component - Interpolation (2)
* 在AppComponet使用HeaderComponent
app.component.html
```htmlmixed=
<header class="header">
<!-- <h1>{{title}}</h1> -->
<app-header></app-header>
<input class="new-todo"
placeholder="What needs to be done?" autofocus>
</header>
```
----
### 內嵌繫結 - 補充說明
![](https://i.imgur.com/wfkQcNn.png)
----
### 內嵌繫結 - 注意事項
* 透過內嵌繫結輸出,無論是甚麼型別的物件,最終都會轉換成「字串」輸出。
* 不要在內嵌繫結中對任何元件、屬性進行更新動作,避免Side Effect。
* 範本表達式看起來像JS語法,並非全部都能用。
* 其他使用限制
* 不能使用 window 或 document 等全域變數
* 不能使用 console.log 或 Math.xxx 等方法
---
### 任務 7-2:屬性繫結 (Property Binding)
* 在 AppComponent 中建立一個 inputHint 屬性
* 在 app.component.html 中使用屬性繫結套用 inputHint 到 <input> 的 placeholder 屬性裡
* 屬性繫結語法:```<img [src] = 'imgUrl' />```
```
<element-tag [element-property]='my-variable'></element-tag>
```
----
### AppComponent - Property Binding
app.component.ts
```typescript=
@Component({
// ...
})
export class AppComponent implements OnInit {
inputHint:string = 'Please input your todo item';
}
```
app.component.html
```htmlembedded=
<header class="header">
<app-header></app-header>
<!-- <input class="new-todo"
placeholder="..." autofocus> -->
<input class="new-todo"
[placeholder]="inputHint" autofocus>
</header>
```
----
### 屬性繫結 - 注意事項
* ```[property]='variable'```
傳入property的variable其物件型別需一致
* 只有符合以下條件,使用屬性繫結時可不加 [ ]
* property為可以接受「字串」型別的物件
* 傳入property的值是固定或不會變更的
---
### 任務 07-3:事件繫結 (Event Binding)
* 在 AppComponent 元件中新增一個 todos 陣列,型別為 any[]
* 在輸入框輸入任何文字,只要按下 Enter 鍵就會自動加入到 todos 陣列中
* 事件繫結語法:
```
<element-tag (element-event)='class-method'></element-tag>
```
```
<button (click)="doSomething()">Click</button>
```
---
### AppComponent - Event Binding (1)
app.component.ts
```typescript=
export class AppComponent implements OnInit {
inputHint:string = 'Please input your todo item';
todos:any[] = [];
constructor() { }
ngOnInit() {}
addTodo(todoval:string){
this.todos.push(todoval);
}
}
```
----
### AppComponent - Event Binding (2)
app.component.html
```htmlembedded=
<header class="header">
<app-header></app-header>
<input class="new-todo" [placeholder]="inputHint"
#todoInput (keyup.enter)="addTodo(todoInput.value)"
autofocus>
</header>
```
* #為範本參考變數(template reference variable)
* 可以對任意 HTML element 加上 # 與變數名稱
* Angular 會自動對該 element 建立物件
----
### 事件繫結 - 補充說明(1)
參考:[Sam的部落格](http://oomusou.io/angular/angular-select/)
event method 傳入資料的方式有幾種
* 使用 Template Reference Variable (本例使用)
* 使用 DOM event
```typescript=
// in app.component.html
<input class="new-todo" [placeholder]="inputHint"
(keyup.enter)="addTodo($event)" >
// in app.component.ts
addTodo(event: Event) {
this.todos.push(
(<HTMLSelectElement>event.target).value
);
}
```
----
### 事件繫結 - 補充說明(2)
參考:[Angular官網 User Input](https://angular.io/guide/user-input)
* keyup事件會監聽每一次按鍵
* 如果需要在某些按鍵按下時才做動作,可使用$event.keyCode找出按下什麼按鍵
* (keyup.enter)是內建可感知按下enter才做動作的簡單寫法
---
### 任務 7-4:雙向繫結(TwoWay Binding)
* 在 AppComponent 元件中新增一個 todo 屬性 (型別為字串)
* 設定 <input> 與 todo 屬性雙向繫結
* 雙向繫結語法:```[(ngModel)]="xxxx"```
```typescript=
// two one-way binding
<input type="text"
[value]="todoText" // property binding
(change)="changeTodoText($event)"> // event binding
// two-way binding
<input type="text" [(ngModel)]="todoText" />
```
----
### AppComponent - TwoWay Binding (1)
app.component.ts
```typescript=
export class AppComponent implements OnInit {
inputHint:string = 'Please input your todo item';
todos:any[] = [];
todo:string;
}
```
----
### AppComponent - TwoWay Binding (2)
app.component.html
```htmlembedded=
<header class="header">
<app-header></app-header>
<input class="new-todo" #todoInput
[placeholder]="inputHint"
(keyup.enter)="addTodo(todoInput)"
[(ngModel)]="todo" autofocus>
</header>
```
----
### AppComponent - TwoWay Binding (3)
app.component.ts
```typescript=
export class AppComponent implements OnInit {
todo:string;
addTodo(todoInput:HTMLInputElement){
this.todos.push(this.todo);
todoInput.value = null;
}
}
```
---
## Next is 「 Directives 」
## 11:00 ~ 12:00 by Jimmy
{"metaMigratedAt":"2023-06-14T14:04:00.205Z","metaMigratedFrom":"Content","title":"Component 介紹","breaks":true,"contributors":"[]"}