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":"[]"}
    1960 views