1、簡介
2016年9月15號,Angular2 正式版本發佈。Angular2 不向下兼容 AngularJS。
Angular2 新特性:
- 移除了 controller + $scope 設計,改用組件式開發(容易上手);
- 性能更好(渲染更快,變化監測效率更高);
- 優先爲移動應用設計(Angular Mobile Toolkit 套件);
- 更加貼合未來的標準(如 ES6/7、 WebComponent)
UpgradeAdapter 使得 AngularJS 和 Angular2 相互兼容。
2、Angular2 核心概念
Angular2 核心概念:
- 組件(Components)
- 元數據(MetaData)
- 模板(Templates)
- 數據綁定(Data binding)
- 服務(Services)
- 指令(Directives)
- 依賴注入(Dependency Injection)
- 模塊(Modules)
2.1、組件及組件樹
每個組件包含 JavaScript、 HTML、 CSS。每個組件都有各自的輸入輸出,用於各個組件之間通信。
組件的生命週期(部分):
- Constructor:構造器初始化
- OnChanges:第一次觸發數據變化鉤子(用於接收父組件傳來的參數)
- OnInit:組件初始化
- OnChanges:運行期間觸發數據變化鉤子
- OnDestroy:組件銷燬前
組件由兩大部分組成:組件類和裝飾器(裝飾器裏面是元數據)
@Component({ // 裝飾器
// 元數據
selector: 'hello'; // CSS3 選擇器 匹配hello標籤
template: '<p>{{greeting}}</p>'; // 定義模板,可以使用 templateUrl 引入外部模板
})
export class HelloComponent{ // 組件類
private greeting: string;
constructor(){
this.greeting = 'hello';
}
}
裝飾器:賦予一個類更豐富的信息(元數據)。
數據綁定:
- 插值綁定(interpolation):如上面的 greeting
屬性綁定 :[value] 把組件類的數據傳入到組件模板中
<input [value]="data" />
事件綁定:(keyup)把模板產生的數據通過函數調用傳遞給組件類
<input (keyup)="handle($event)" />
雙向綁定:[(ngModel)] 實現數據的雙向流動
<input [(ngModel)]="data" />
父子組件
@Component({ template: `< child [data]="item">< /child>` }) export class Parent{} @Component({ selector: 'child' }) export class Child{ @Input() data: IContact; // 子組件的輸入接口,用於接收父組件的數據 }
2.2、指令
組件是自身帶有模板的指令。
指令分爲:
- 屬性指令:改變組件模板的外觀或行爲,如樣式等
結構指令:改變組件模板的 DOM 結構,如 ngIf 用來插入或者移除 DOM 節點。(ElementRef、Renderer 與 DOM 相關的對象)
// ngIf <input type="checkbox" [(ngModel)]="isShowMore"> <p highlight *ngIf="isShowMore"></p> // ElementRef、Renderer import { Directive, ElementRef, Renderer } from '@angular/core'; @Directive({ selector: "[highlight]" // 中括號表示指令使用在元素屬性上 }) export class HighlightDirective { constructor( private el: ElementRef, private renderer: Renderer ) { renderer.setElementStyle(el.nativeElement, 'backgroundColor', 'yellow'); } } <p highlight></p>
2.3、服務
服務是實現專一目的的邏輯單元,如日誌服務
export class LoggerService{
constructor(){}
debug(msg: string){}
error(msg: string){}
}
依賴注入機制是組件引入外部構建(如服務)的一種機制。服務的實例保存在依賴注入機制建立的注入器對象裏。當組件需要依賴某個服務時,依賴注入機制會從注入器中查找匹配的實例,找到後並執行注入操作。當組件注入服務後,它及它的子組件都能使用該服務,並且是單例模式。
@Component({
providers: [LoggerService] // 依賴注入配置
})
export class Hello{
constructor(logger: LoggerServoce){ // 從注入器中查找LoggerService實例,找到後自動傳入 LoggerService 實例
logger.debuge("OK");
}
}
分層注入:在需要改進的地方重新注入改進的服務即可。
2.4、模塊
模塊有兩層含義:
- 框架代碼以模塊形式組織(文件模塊)
- 功能單元以模塊形式組織(應用模塊)
聲明模塊使用 @NgModule 裝飾器
@NgModule({
declarations:[],// 包裝組件或指令等
providers:[], // 依賴注入
imports:[], // 導入其他模塊
bootstrap:[], // 設置根組件
exports:[] // 導出組件或指令等
})
3、父子組件交互
// 子組件
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'my-child',
template: <div class="cmp-2">
<h1>子組件</h1>
<p>嘿嘿,我從父組件獲取的值是:{{ message }}</p>
<button (click)="sendToParent()">發送到父組件</button>
</div>
})
export class ChildComponent {
@Input() private message: string;
@Output() private outer = new EventEmitter<string>();
constructor() { }
sendToParent() {
this.outer.emit('message from child');
}
}
//父組件
@Component({
selector: 'my-app',
templateUrl: <my-child [message]="msgToChild" (outer)="receive($event)"></my-child>
<p>從子組件獲得的消息:{{ msgFromChild || '暫無' }}</p>
})
export class AppComponent {
private greeting: string;
private isShowMore: boolean;
private msgToChild: string;
private msgFromChild: string;
constructor(private logger: LoggerService) { }
ngOnInit() {
this.greeting = 'Angular 2';
this.msgToChild = 'message from parent';
this.logger.debug('應用已初始化');
}
receive(msg: string) {
this.msgFromChild = msg;
}
}