一個Angular專案基本上是由數個Component組成
一個Componet還可以包含很多個子Component
Component各司其職,適當的彼此溝通
Componet = Import + Template & Metadata + Class
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app works!';
}
ES6的Decorator語法
使用@Component({…})將class"裝飾"成元件
{…} 用來讓Angular核心知道如何建構元件
@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: 此元件的 樣式檔案 位置
Inline的優點是只需一個檔案就能完成Component
缺點是沒有Intellisense 容易出錯,建議使用Linked
@Component({
// ...
})
export class AppComponent {
title:string = 'app works!';
clickTitle() { ... }
}
類別名稱,使用Pascal命名法
最好加上Component字眼,標示其為元件
加上 export 關鍵字,可讓其他程式使用
@Component({
// ...
})
export class AppComponent {
appTitle:string = 'app works!'; // data in class property
clickTitle() { ... } // login in class method
}
property、method 使用 Lower Camel Casing
property 定義資料模型,並設定型別及初始值
method 封裝程式邏輯
將 app.component.ts 中的 title 屬性移到 title.component.ts 檔案中
透過 內嵌繫結 (Interpolation) 將 title 屬性顯示在 Template 的 h1 標籤內
內嵌繫結語法:{{variable}}
header.component.html
<h1>{{title}}</h1>
header.component.ts
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() {} }
app.component.html
<header class="header"> <!-- <h1>{{title}}</h1> --> <app-header></app-header> <input class="new-todo" placeholder="What needs to be done?" autofocus> </header>
透過內嵌繫結輸出,無論是甚麼型別的物件,最終都會轉換成「字串」輸出。
不要在內嵌繫結中對任何元件、屬性進行更新動作,避免Side Effect。
範本表達式看起來像JS語法,並非全部都能用。
其他使用限制
不能使用 window 或 document 等全域變數
不能使用 console.log 或 Math.xxx 等方法
在 AppComponent 中建立一個 inputHint 屬性
在 app.component.html 中使用屬性繫結套用 inputHint 到 <input> 的 placeholder 屬性裡
屬性繫結語法:<img [src] = 'imgUrl' />
<element-tag [element-property]='my-variable'></element-tag>
app.component.ts
@Component({ // ... }) export class AppComponent implements OnInit { inputHint:string = 'Please input your todo item'; }
app.component.html
<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的值是固定或不會變更的
在 AppComponent 元件中新增一個 todos 陣列,型別為 any[]
在輸入框輸入任何文字,只要按下 Enter 鍵就會自動加入到 todos 陣列中
事件繫結語法:
<element-tag (element-event)='class-method'></element-tag>
<button (click)="doSomething()">Click</button>
app.component.ts
export class AppComponent implements OnInit { inputHint:string = 'Please input your todo item'; todos:any[] = []; constructor() { } ngOnInit() {} addTodo(todoval:string){ this.todos.push(todoval); } }
app.component.html
<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 建立物件
參考:Sam的部落格
event method 傳入資料的方式有幾種
使用 Template Reference Variable (本例使用)
使用 DOM event
// 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 ); }
keyup事件會監聽每一次按鍵
如果需要在某些按鍵按下時才做動作,可使用$event.keyCode找出按下什麼按鍵
(keyup.enter)是內建可感知按下enter才做動作的簡單寫法
在 AppComponent 元件中新增一個 todo 屬性 (型別為字串)
設定 <input> 與 todo 屬性雙向繫結
雙向繫結語法:[(ngModel)]="xxxx"
// two one-way binding <input type="text" [value]="todoText" // property binding (change)="changeTodoText($event)"> // event binding // two-way binding <input type="text" [(ngModel)]="todoText" />
app.component.ts
export class AppComponent implements OnInit { inputHint:string = 'Please input your todo item'; todos:any[] = []; todo:string; }
app.component.html
<header class="header"> <app-header></app-header> <input class="new-todo" #todoInput [placeholder]="inputHint" (keyup.enter)="addTodo(todoInput)" [(ngModel)]="todo" autofocus> </header>
app.component.ts
export class AppComponent implements OnInit { todo:string; addTodo(todoInput:HTMLInputElement){ this.todos.push(this.todo); todoInput.value = null; } }