使用angular開發也有快2年的時間,突然有一天有人問我,你能不能給我簡單講一下angular框架?雖然每天都在使用,卻不知如何表述,故決定寫這樣一篇文章。
Angular本身就是用 TypeScript 寫成的,核心功能和可選功能作爲一組 TypeScript庫,根據需要導入到應用中;
Angular 的基本構建塊是 NgModule(特性模塊),爲組件提供編譯的上下文環境。Angular應用就是由一組NgModule定義的, NgModule 可以將其組件和一組相關代碼(如服務)關聯起來,形成功能單元;
組件定義視圖,由html模板+css樣式+ts組件類構成,也可以根據需要引入服務類。
模板把傳統的html和angular模板語法結合起來,是HTML的升級版(插值,屬性綁定,雙向數據綁定,事件綁定,指令,結構指令,屬性指令,管道等等);
css樣式可以使用scss和less進行預擴展;
組件類定義應用的數據和業務邏輯;
組件可以把服務類通過DI依賴注入到組件中;
通過Router服務在多個視圖之間進行導航功能;
不過路由器會把類似 URL 的路徑映射到視圖而不是頁面。 當用戶執行一個動作時(比如點擊鏈接),本應該在瀏覽器中加載一個新頁面,但是路由器攔截了瀏覽器的這個行爲,並顯示或隱藏一個視圖層次結構;
如果路由器認爲當前的應用狀態需要某些特定的功能,而定義此功能的模塊尚未加載,路由器就會按需惰性加載此模塊;
導航路徑和你的組件關聯起來。 路徑(path)使用類似 URL 的語法來和程序數據整合在一起,就像模板語法會把你的視圖和程序數據整合起來一樣。 然後你就可以用程序邏輯來決定要顯示或隱藏哪些視圖,以根據你制定的訪問規則對用戶的輸入做出響應;
裝飾器類型:
@Component()
@Injectable()
以上是視圖的構成:
組件和模板共同構成了視圖:
它就是一個容器,存放一些內聚的代碼塊,使用某個特定的功能。它可以包含組件,服務提供商,其他代碼文件等。
@NgModule函數的入參:
declarations(可聲明對象表) —— 那些屬於本 NgModule 的組件、指令、管道。
exports(導出表) —— 那些能在其它模塊的組件模板中使用的可聲明對象的子集。
imports(導入表) —— 那些導出了本模塊中的組件模板所需的類的其它模塊。
Providers(服務提供商) —— 本模塊向全局服務中貢獻的那些服務的創建器。 這些服務能被本應用中的任何部分使用。(你也可以在組件級別指定服務提供商,這通常是首選方式。)
Bootstrap(啓動項) —— 應用的主視圖,稱爲根組件。它是應用中所有其它視圖的宿主。只有根模塊才應該設置這個 bootstrap 屬性;
NgModule和組件:
NgModule可以declaration任意數量的其他組件,這些組件可以是通過路由加載,或者是通過模板創建,他們都屬於這個NgModule的組件會共享同一個編譯上下文環境,即爲,imports的模塊(服務類,框架的模塊)都可以在組件中使用。
組件還可以包含視圖層次結構。一個視圖層次結構可以混合使用由不同NgModule中的組件定義的視圖,比如UI庫。宿主視圖爲起點,下面包含內嵌視圖。
組件構成視圖的一部分。在組件類彙總定義它的應用邏輯,通過定義屬性和方法組成的API與視圖交互。
組件可以通過TS的構造器參數性屬性,通過依賴注入系統將服務提供給該組件。
組件都有生命週期鉤子(lifecycle hooks),因爲ng會在應用的過程中,對組件進行create、update、destroy操作,故可以根據需要在對應的鉤子環節添加額外的應用邏輯。
組件的元數據:
@Component裝飾器後面緊跟的類就代表一個組件類(類似於JAVA的註解),併爲其制定metadata元數據,即爲函數的入參。
元數據告訴angular到哪裏獲取它的主要構造塊,來創建和展示這個組件及其視圖。具體來說,它把模板和該組件關聯起來,該組件及其模板,共同描述一個視圖。
具體配置項如下:
selector:是一個 CSS 選擇器,它會告訴 Angular,一旦在模板 HTML 中找到了這個選擇器對應的標籤,就創建並插入該組件的一個實例的視圖。
templateUrl:該組件的 HTML 模板文件相對於這個組件文件的地址。 另外,你還可以用 template 屬性的值來提供內聯的 HTML 模板。 這個模板定義了該組件的宿主視圖。
providers:當前組件所需的服務提供商的一個數組。
模板與視圖
與組件直接關聯的模板就叫宿主視圖,該組件還可以定義一個帶層次結構的視圖,在模板裏引入其他組件關聯的模板(可以是任何模塊中定義的組件),他們就叫內嵌視圖。
模板語法
傳統HTML與angular模板語法結合,他可以使用數據綁定來協調應用和DOM中的數據,使用Pipes管道對數據進行轉換,使用Directives指令在內容上添加邏輯代碼。
數據綁定
數據綁定標記有四種形式,每種形式有方向性的,如下圖:
雙向數據綁定主要用於模板驅動表單,在Form元素中使用,代指起value屬性(語法糖:將屬性綁定和事件綁定合作成一種獨特的寫法)。
父子直接通信原理,如下圖:
管道
@Pipe()
作用在模板中聲明的顯示值,做一個對應的轉換的一個轉換函數。
使用時,使用管道操作符 |
指令
@Directive()
理論上,組件就是一個指令。
Angular的模板是動態的,只有當渲染他們的時候解析,根據指令給出的指示對DOM進行轉換。
分類:結構指令 / 屬性指令.
結構指令:通過添加,移除,替換DOM元素來修改佈局。
屬性指令:修改元素的外觀或行爲。
服務與DI
@Injectable()
組件僅僅提供用於視圖模板中數據綁定的屬性和方法,讓組件更加精簡和高效。
可以將諸如從服務器上獲取數據,驗證用戶輸入等委託給各種服務,提高模塊化和複用性。
依賴注入
組件是服務的消費者。
機制:
注入器injector:在ng啓動過程中會自動創建全應用級注入器;
注入器會創建依賴,通過維護一個容器來管理這些依賴,複用;
提供商provider:告訴注入器如何創建或獲取依賴,即爲新實例。
提供服務
服務可以在自己的metadata元數據中註冊爲提供商;
爲特定的模板或組件註冊提供商,在@NgModule()或@Component()元數據中提供;
示例:
方式一:類本身上創建一個單一的共享實例,任何類中都可以直接調用;
這種方式可以讓可以讓ng通過移除那些未被使用過的服務來優化大小;
方式二:在模塊中創建服務商,該服務的作用範圍僅在該NgModule中的所有組件可用;
方式三:在組件註冊provider,爲該組件的每一個新實例提供該服務的一個新實例;
通過 interface 創建模型類,作爲某個組件類的屬性的類型(TS的類型檢查);
基礎常識:
父子通信:
[hero]="selectedHero" 是 Angular 的屬性綁定語法;
這是一種單向數據綁定。從 父組件的 selectedHero 屬性綁定到目標元素的 hero 屬性,並映射到了子組件的 hero 屬性;
爲什麼需要服務
因爲組件的職責是聚焦於展示數據,處理與視圖的數據交互,而不關心如何獲取或保存數據,把這個工作的職責委託給某個服務;
服務可以在多個「相互不知道」的類之間共享信息;
服務提供商provider:某種可以創建或交付一個服務的東西;
組件的構造函數的參數:
特別注意:
服務的一個基本流程:
Router基礎開發
{ path: 'detail/:id', component: HeroDetailComponent }
path路徑中的冒號 ( : )表示:某個名稱是一個佔位符,可以在路由參數中獲取;
拿路由參數:
HTTP基礎應用
HttpClient是Angular通過HTTP與遠程服務器通訊的重要機制;
在根模塊中導入HttpClientModule模塊;
HttpClient的Observable總是發出一個值,然後complete,不會再發出其他值;
內部捕獲錯誤,pipe中的catchError攔截失敗的observable,可以定義一個方法來返回安全值,讓應用繼續正常運行;
AsyncPipe管道
<li *ngFor="let hero of heroes$ | async" >
Heroes$中,$是一個約定,表示它是一個Observable;
在模板中可以使用async管道,自動訂閱Observable,就不必在組件類中subscribe;
Rxjs的各種操作符(核心庫)
通過Observable來編寫異步和基於事件的庫;
基本概念:
學習Rx,主要就是學習各種操作符,這裏就不展開介紹。
以上就是Angular框架的整體介紹,掌握了它的基本運行原理。不僅會用,還能很好的表達出來。