Angular 是一個用 HTML 和 TypeScript 構建客戶端應用的平臺與框架。 Angular 本身使用 TypeScript
寫成的。它將核心功能和可選功能作爲一組 TypeScript 庫進行實現,你可以把它們導入你的應用中。
一:模塊
NgModule 爲一個組件集聲明瞭編譯的上下文環境,NgModule 可以將其組件和一組相關代碼(如服務)關聯起來,形成功能單元
每個 Angular 應用都有一個根模塊,通常命名爲 AppModule。根模塊提供了用來啓動應用的引導機制。
一個應用通常會包含很多功能模塊。
像 JavaScript 模塊一樣,NgModule 也可以從其它 NgModule 中導入功能,並允許導出它們自己的功能供其它
NgModule 使用。 比如,要在你的應用中使用路由器(Router)服務,就要導入 Router 這個 NgModule。
export class AppModule { } //導出
import { AppModule } from './app/app.module'; //導入
這項技術還能讓你獲得按需加載模塊的優點,以儘可能減小啓動時需要加載的代碼體積。
NgModule 是一個帶有 @NgModule 裝飾器的類,@NgModule 裝飾器是一個函數,它接受一個元數據對象,該對象的屬性用來描述這個模塊
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
@NgModule({
imports: [ BrowserModule ],
providers: [ Logger ],
declarations: [ AppComponent ],
exports: [ ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
解釋
declarations(可聲明對象表)—— 聲明屬於本 NgModule 的組件、指令、管道。
exports(導出表) —— 那些能在其它模塊的組件模板中使用的可聲明對象的子集,爲空是因爲根模塊沒有任何理由導出任何東西,因爲其它模塊永遠不需要導入根模塊。
imports(導入表) —— 導入其他模塊
providers —— 定義服務,這些服務能被本應用中的任何部分使用。(你也可以在組件級別指定服務提供商,這通常是首選方式。在這裏面定義之後在組件裏面只需要注入不需要在組件內定義了)
bootstrap —— 應用的主視圖,稱爲根組件。它是應用中所有其它視圖的宿主。只有根模塊才應該設置這個 bootstrap 屬性。
NgModule與組件的關係:
根模塊總會有一個根組件,並在引導期間創建它,
比如前面介紹的元數據bootstrap中定義的AppComponent就是 AppModule的根組件
任何模塊都能包含任意數量的組件,這些組件可以通過路由器加載,也可以通過模板創建。屬於這個 NgModule
的組件會共享這個模塊提供的同一個編譯上下文環境。
angular自帶的庫
Angular 自帶了一組 JavaScript 模塊,你可以把它們看成庫模塊。每個 Angular 庫的名稱都帶有 @angular
前綴。 使用 npm install 包管理器安裝它們,並使用 JavaScript 的 import 語句導入其中的各個部分。
import { Component } from '@angular/core'; //從 @angular/core 庫中導入 Component 裝飾器
import { BrowserModule } from '@angular/platform-browser'; //從 Angular 庫中導入 Angular 模塊:這個代碼從 platform-browser 庫中導入了 BrowserModule 模塊
NgModule 和 JavaScript 的模塊
這兩種模塊系統不同但互補。你可以同時使用 Angular 和 JavaScript 的這兩種模塊系統。 雖然這兩種模塊系統容易混淆(它們共享了同樣的詞彙 import 和export)
二:組件
下面的例子中就是 HeroListComponent 的基礎元數據:
@Component({
selector: 'app-hero-list',
templateUrl: './hero-list.component.html',
providers: [ HeroService ]
})
export class HeroListComponent implements OnInit {
/* . . . */
}
組件控制視圖上的一小片區域,視圖都是由一個個組件所組成和控制的
組件通過一些由屬性和方法組成的 API 與視圖交互。
export class HeroListComponent implements OnInit {
heroes: Hero[];
selectedHero: Hero;
constructor(private service: HeroService) { }
ngOnInit() {
this.heroes = this.service.getHeroes();
}
selectHero(hero: Hero) { this.selectedHero = hero; }
}
比如上面的組件就由heroes、selectedHero屬性以及 selectHero()方法與視圖進行數據交互的
每個 Angular 應用都至少有一個組件,也就是根組件—AppComponent,每個組件都會定義一個類,其中包含應用的數據和邏輯
@Component 裝飾器表明緊隨它的那個類是一個組件,並提供模板和該組件專屬的元數據。
模板與視圖
模板就是一種 HTML,它會告訴 Angular 如何渲染該組件
模板很像標準的 HTML,但是它還包含 Angular 的模板語法,你的模板可以使用數據綁定加粗樣式來協調應用和 DOM
中的數據,使用管道在顯示出來之前對其進行轉換,使用指令來把程序邏輯應用到要顯示的內容上。
<h2>Hero List</h2>
<p><i>Pick a hero from the list</i></p>
<ul>
<li *ngFor="let hero of heroes" (click)="selectHero(hero)">
{{hero.name}}
</li>
</ul>
<app-hero-detail *ngIf="selectedHero" [hero]="selectedHero"></app-hero-detail>
上面的例子使用了典型的 HTML 元素,比如 <h2> 和 <p>,還包括一些 Angular 的模板語法元素,如 *ngFor(指令),{{hero.name}}(數據綁定),click(數據綁定)、[hero] (數據綁定)和 <app-hero-detail>(組件的子組件)
1:數據綁定
Angular 支持雙向數據綁定
數據綁定標記有四種形式。每種形式都有一個方向 —— 從組件到 DOM、從 DOM 到組件或雙向
<li>{{hero.name}}</li>
<app-hero-detail [hero]="selectedHero"></app-hero-detail>
<li (click)="selectHero(hero)"></li>
<input [(ngModel)]="hero.name">
分析:
1:{{}}:插值表達式 從組件---DOM
2:[hero] = ''selectedHero'' 屬性綁定,把父組件 HeroListComponent 的 selectedHero 的值傳到子組件 HeroDetailComponent 的 hero 屬性中。從組件---DOM
3:(click)=''selectHero(hero)''事件綁定 從DOM---組件
4:[(ngModel)] = ''hero.name'' 雙向綁定 從DOM<>組件
在雙向綁定中,數據屬性值通過屬性綁定從組件流到輸入框。用戶的修改通過事件綁定流回組件,把屬性值設置爲最新的值。
數據綁定在模板及其組件之間的通訊中扮演了非常重要的角色,它對於父組件和子組件之間的通訊也同樣重要。
2:管道
帶有 @Pipe 裝飾器的類中會定義一個轉換函數,用來把輸入值轉換成供視圖顯示用的輸出值。
Angular 自帶了很多管道,比如 date 管道和 currency 管道,你也可以自己定義一些新管道。
語法:{{value_name| pipe_name}}
3:指令
Angular 的模板是動態的。當 Angular 渲染模板的時候,會根據指令給出的指示對 DOM 進行轉換。 指令就是一個帶有
@Directive 裝飾器的類。
組件從技術角度上說就是一個指令,除組件外,還有兩種指令:結構型指令和屬性型指令。
<1結構型指令
結構型指令通過添加、移除或替換 DOM 元素來修改佈局
<li *ngFor="let hero of heroes"></li>
<app-hero-detail *ngIf="selectedHero"></app-hero-detail>
<2屬性型指令
屬性型指令會修改現有元素的外觀或行爲。 在模板中,它們看起來就像普通的 HTML 屬性一樣,因此得名“屬性型指令”
ngModel 指令就是屬性型指令的一個例子,它實現了雙向數據綁定。 ngModel 修改現有元素(一般是 )的行爲:設置其顯示屬性值,並響應 change 事件。Angular 還有很多預定義指令,它們或者修改佈局結構(比如 ngSwitch),或者修改 DOM 元素和組件的某些方面(比如 ngStyle 和 ngClass)。
<input [(ngModel)]="hero.name">
三:服務與依賴注入
<1:服務
比如你寫了一個公共的方法,這個方法將在很多組件中用到,你就可以把這個公共方法寫進一個服務裏面,到時候只需要在不同組件引入這個服務就好,我理解的服務就是服務組件的類,Angular 把組件和服務區分開,以提高模塊性和複用性。
對於與特定視圖無關並希望跨組件共享的數據或邏輯,可以創建服務類
服務類的定義通常緊跟在 “@Injectable” 裝飾器之後
該裝飾器提供的元數據可以讓你的服務作爲依賴被注入到客戶組件中。
下面是一個服務類的範例,用於把日誌記錄到瀏覽器的控制檯:
export class Logger {
log(msg: any) { console.log(msg); }
error(msg: any) { console.error(msg); }
warn(msg: any) { console.warn(msg); }
}
服務也可以依賴其它服務
<2:依賴注入(DI)
你可以把一個服務注入到組件中,讓組件類得以訪問該服務類,在 Angular 中,要把一個類定義爲服務,就要用 @Injectable
裝飾器來提供元數據,以便讓 Angular 可以把它作爲依賴注入到組件中
constructor(private service: HeroService) { }
對於任何服務,你必須至少註冊一個提供商,你也可以爲特定的模塊或組件註冊提供商。要註冊提供商,就要在服務的 @Injectable 裝飾器中提供它的元數據providedIn,或者在@NgModule 或 @Component 的元數據providers中。
@Injectable({
providedIn: 'root',
})
當你在組件級註冊提供商時,你會爲該組件的每一個新實例提供該服務的一個新實例。 要在組件級註冊,就要在 @Component 元數據的
providers 屬性中註冊服務提供商。
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers:[]
})
當你使用特定的 NgModule 註冊提供商時,該服務的同一個實例將會對該 NgModule 中的所有組件可用。要想在這一層註冊,請用
@NgModule 裝飾器中的 providers 屬性
@NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule,
],
providers: [],
bootstrap: [AppComponent]
})
五:路由
它的工作模型基於人們熟知的瀏覽器導航約定
不過路由器會把類似 URL 的路徑映射到視圖而不是頁面,當用戶執行一個動作時(比如點擊鏈接),本應該在瀏覽器中加載一個新頁面,但是路由器攔截了瀏覽器的這個行爲,並顯示或隱藏一個視圖層次結構。
如果路由器認爲當前的應用狀態需要某些特定的功能,而定義此功能的模塊尚未加載,路由器就會按需惰性加載此模塊。
這五個概念會有詳細的教程。。。