angular學(xué)習(xí)筆記

angular程序架構(gòu)

一、搭建Angular開(kāi)發(fā)環(huán)境

安裝nodejs, Angular Cli, WebStorm

先安裝nodejs, 安裝完成后用命令來(lái)安裝Angular Cli
npm install -g @angular/cli

使用Angular Cli創(chuàng)建并運(yùn)行Angular項(xiàng)目

用ng new 命令來(lái)創(chuàng)建一個(gè)項(xiàng)目,比如項(xiàng)目名為demo,則輸入命令 ng new demo

分析Angular目錄結(jié)構(gòu)及Angular Cli 生成的基礎(chǔ)代碼

e2e 端到端的測(cè)試目錄,用來(lái)做自動(dòng)測(cè)試的
node_modules 第三方的依賴(lài)包
src 源代碼目錄
app 包含應(yīng)用的組件和模塊
assets 用來(lái)存放靜態(tài)資源文件
environment 環(huán)境配置,支持多環(huán)境開(kāi)發(fā),比如開(kāi)發(fā)環(huán)境和生產(chǎn)環(huán)境可以共用一套代碼
index.html 整個(gè)應(yīng)用的根文件
main.ts 整個(gè)應(yīng)用的入口點(diǎn)
polyfills.ts 導(dǎo)入必要的庫(kù),使angular可以正常運(yùn)行在老版本的瀏覽器
style.css 應(yīng)用的全局樣式
test.ts 做自動(dòng)化測(cè)試的
tsconfig.json ts的配置文件
.editconfig webStorm的配置文件
.gitignore git的配置文件
angular-cli.json angular命令行工具的配置文件
karma.config.js karma的配置文件,用來(lái)執(zhí)行自動(dòng)化測(cè)試的
package.json 標(biāo)準(zhǔn)的npm工具的配置文件,當(dāng)前應(yīng)用使用的第三方工具包,通過(guò)npm i 來(lái)安裝
protractor.conf.js 跟karma類(lèi)似,也是用來(lái)做自動(dòng)化測(cè)試
tslint.json 用來(lái)定義ts代碼的質(zhì)量檢查

二、組件

定義:在angular中組件就是一個(gè)ts類(lèi),然后通過(guò)@Component裝飾器裝飾,裝飾器里面定義了組件的元數(shù)據(jù),包括樣式,模板等等。

組件要素

必備

裝飾器、模板和控制器

可選

輸入屬性@Input---父組件向子組件傳遞數(shù)據(jù)
提供器 providers---用來(lái)做依賴(lài)注入
生命周期鉤子
樣式表
動(dòng)畫(huà)---angular 提供動(dòng)畫(huà)包幫助我們創(chuàng)建組件間的動(dòng)畫(huà)效果
輸出屬性---用來(lái)在組件間共享數(shù)據(jù)

模塊

用@NgModule裝飾器裝飾的一個(gè)ts類(lèi)

元數(shù)據(jù)

declarations 只能聲明組件,指令和管道
imports 引用app模塊需要依賴(lài)的模塊
providers 用來(lái)聲明模塊中提供什么服務(wù),只能聲明服務(wù)
bootstrap 聲明模塊的主組件

三、Angular路由

Routes

路由配置,保存著哪個(gè)URL對(duì)應(yīng)展示哪個(gè)組件,以及在哪個(gè)RouterOutlet中展示

RouterOutlet

在HTML中標(biāo)記路由內(nèi)容呈現(xiàn)位置的占位符指令

Router

路由的對(duì)象,用來(lái)跳轉(zhuǎn)路由,在控制器使用

RouterLink

在HTML中聲明路由導(dǎo)航用的指令,根路由要用‘/’開(kāi)頭,參數(shù)是一個(gè)數(shù)組。.比如 <a [routerLink]="['/']"></a>

ActivatedRoute

當(dāng)前激活的路由對(duì)象,保存著路由信息。

在路由中傳遞參數(shù)的三種方式:

1、在查詢(xún)參數(shù)中傳遞
 /product?id=1&name=2     =>      ActivatedRoute.queryParams[id]
2、在路由路徑中傳遞參數(shù)
 {path:'product/:id'}     =>     /product/1     =>      ActivatedRoute.params[id]
3、在路由配置中傳遞參數(shù)
 {path:'product', data:[{isProd:true}]}     =>      ActivatedRoute.data[0][isProd]

參數(shù)訂閱和參數(shù)快照snapshot

如果不會(huì)出現(xiàn)組件路由到自身的情況,則可使用參數(shù)快照來(lái)獲取參數(shù)。如果會(huì)出現(xiàn)路由到自身的情況,則用參數(shù)訂閱,也就是subcribe()方法。

為什么要這樣做?
這是因?yàn)?,?dāng)組件路由到自身的時(shí)候,由于組件已經(jīng)被創(chuàng)建,那么就不會(huì)再執(zhí)行ngOninit方法。而通過(guò)訂閱則可以解決這個(gè)問(wèn)題。

重定向路由

在用戶(hù)訪問(wèn)特定的地址時(shí),將其重定向到其他的地址
可用redirectTo屬性

子路由

路由間的父子關(guān)系,可以無(wú)限嵌套
在用RouterLink指令時(shí),路由要用'./'開(kāi)頭,表示從當(dāng)前路由開(kāi)始

輔助路由

路由守衛(wèi)

當(dāng)用戶(hù)滿(mǎn)足某種條件后才允許用戶(hù)進(jìn)入或離開(kāi)路由。

CanActivate: 處理導(dǎo)航到路由的情況
CanDeActivate: 處理從當(dāng)前路由離開(kāi)的情況
Resolve: 在路由激活之前獲取路由數(shù)據(jù)

實(shí)現(xiàn):需要?jiǎng)?chuàng)建一個(gè)ts類(lèi),該類(lèi)繼承對(duì)應(yīng)的守衛(wèi)類(lèi),實(shí)現(xiàn)對(duì)應(yīng)的方法。然后在Routes里面加入對(duì)應(yīng)的屬性,再把創(chuàng)建的類(lèi)添加到providers里面。

四、依賴(lài)注入

依賴(lài)注入解決的問(wèn)題

當(dāng)一個(gè)方法或者類(lèi)依賴(lài)其他類(lèi)時(shí),使用前需要先實(shí)例化其他類(lèi)。當(dāng)依賴(lài)的類(lèi)多了,要實(shí)例化所有的類(lèi)也是一件麻煩的事。那么能不能把實(shí)例化的工作交給其他人做, 我們只需要知道依賴(lài)哪些類(lèi),而不需要知道具體的實(shí)例方法。

依賴(lài)注入DI 和 控制反轉(zhuǎn)IOC

依賴(lài)注入:側(cè)重于描述手段,如何來(lái)實(shí)現(xiàn)控制反轉(zhuǎn)的手段
控制反轉(zhuǎn):側(cè)重于描述目的,即依賴(lài)的控制權(quán)由代碼的內(nèi)部轉(zhuǎn)移到代碼的外部

使用依賴(lài)注入的好處

1、松耦合、可重用性
2、提高可測(cè)試性

angular如何實(shí)現(xiàn)

注入器 在構(gòu)造函數(shù)中聲明需要用到的類(lèi)

constructor(private productService: ProductService){}

提供器 在模塊或組件的providers屬性聲明provider

providers:[ProductService]
providers:[provider:ProductService, useClass: ProductService]
providers:[provider:ProductService, useClass: AnotherProductService]

provider指定了提供器的token,跟構(gòu)造器中聲明的類(lèi)對(duì)應(yīng)。
useClass指定了具體實(shí)例化的類(lèi)
providers:[provider:ProductService, useFactory: () => {...}] 工廠提供器
根據(jù)某些條件決定具體實(shí)例化哪些對(duì)象,也有可能在實(shí)例化對(duì)象時(shí)需要傳入?yún)?shù),這時(shí)就需要用到工廠提供器
在使用工廠方法時(shí),如果需要依賴(lài)其他類(lèi),則需要用到第三個(gè)參數(shù)deps:[],在deps的數(shù)組中傳入需要依賴(lài)的類(lèi),然后在useFactory的參數(shù)中傳遞進(jìn)去。
providers:[provider:"APP_CONFIG", useValue: {isDev:false}]
useValue可以傳值,也可以傳對(duì)象

作用域規(guī)則

1、聲明在模塊時(shí),對(duì)所有組件可用
2、當(dāng)提供器聲明在組件時(shí),只對(duì)組件和其子組件可用
3、當(dāng)聲明在模塊和組件具有相同的token時(shí),組件中的提供器會(huì)覆蓋模塊中的提供器
4、優(yōu)先將服務(wù)提供器聲明在組件,只有該提供器對(duì)其他組件不可用時(shí)才聲明在組件中

注入器的層級(jí)關(guān)系

應(yīng)用級(jí)注入器 > 主組件注入器 > 子組件注入器

五、組件間通訊

組件的輸入輸出屬性

輸入屬性:用@Input()裝飾器注解的屬性,屬性綁定是單項(xiàng)的
輸出屬性: 用@Output()裝飾器注解的屬性 ,需要用到EventEmitter。從angular/core引入

聲明: lastPrice: EventEmitter<PriceQuote> = new EventEmitter();
可以通過(guò)emit(value)方法把值發(fā)射出去,父組件就可以通過(guò)子組件的事件綁定接收到數(shù)據(jù)。

使用中間人模式傳遞數(shù)據(jù)

中間人模式:如果組件A和組件B要進(jìn)行通信,他們有共同的父組件,則可以把父組件當(dāng)中間人,A組件把值發(fā)射給父組件,父組件接收后把值通過(guò)B組件的Input屬性傳遞給B組件。

如果兩個(gè)組件沒(méi)有共同的父組件,則可以通過(guò)服務(wù)來(lái)訂閱事件。

組件生命周期及angular的變化發(fā)現(xiàn)機(jī)制

左邊的是組件初始化調(diào)用的事件,紅色的事件只調(diào)用一次,綠色的事件會(huì)被多次調(diào)用。如果組件有輸入屬性,則組件在被初始化時(shí)會(huì)調(diào)用ngOnChanges事件。由于這個(gè)事件是在構(gòu)造器之后調(diào)用,所以不能在構(gòu)造函數(shù)做初始賦值操作,最好是在ngOnInit方法中做初始化操作。


組件生命周期
ngOnChanges什么情況下會(huì)被調(diào)用

1、必須是輸入屬性發(fā)生改變
2、輸入屬性的地址發(fā)生改變,如果輸入屬性是引用類(lèi)型,改變?cè)撟兞康膶傩灾凳遣粫?huì)觸發(fā)ngOnChanges事件

變更檢測(cè)和DoCheck鉤子

變更檢測(cè)是通過(guò)zone.js來(lái)實(shí)現(xiàn)的


變更檢測(cè)

事件會(huì)觸發(fā)變更檢測(cè)機(jī)制,變更檢測(cè)機(jī)制被觸發(fā)就會(huì)調(diào)用DoCheck鉤子。
如果鉤子上有check的鉤子,當(dāng)觸發(fā)變更檢測(cè)機(jī)制,所有帶check的鉤子都會(huì)被調(diào)用,所以在使用帶check的鉤子要非常小心。

@ViewChild裝飾器

可以讓父組件獲取子組件的引用,調(diào)用子組件的方法。

ngAfterViewInit和ngAfterViewChecked

這兩個(gè)方法都是在組件的視圖被組裝完畢才調(diào)用
如果組件有子組件,只有當(dāng)所有子組件的視圖都被組裝完成后,父組件才會(huì)被調(diào)用
不要在這兩個(gè)方法中去改變視圖中綁定的東西,如果想改變,要寫(xiě)在定時(shí)器里面,不然會(huì)拋出異常。

ng-content標(biāo)簽可以把父組件模板中任意的片段投影到子組件中去。

ngAfterContentInit和ngAfterContentChecked

在被投影進(jìn)來(lái)的內(nèi)容組裝完被調(diào)用

ngOnDestroy

在切換路由的時(shí)候調(diào)用
在這個(gè)鉤子反訂閱一個(gè)流或者清除定時(shí)器

六、表單處理

模板式表單

表單的數(shù)據(jù)模型通過(guò)組件模板中的相關(guān)指令來(lái)定義的,會(huì)受限于HTML的語(yǔ)法,所以,模板式表單只適合用于一些簡(jiǎn)單的場(chǎng)景。

NgForm -> FormGroup

angular會(huì)自動(dòng)為form表單添加ngForm指令,如果不想讓它接管,可以在form表單添加ngNoForm指令
ngForm可以在form之外使用,比如在div中添加
ngForm可以被模板本地變量引用

NgModule -> FormControl
NgModuleGroup -> FormGroup

響應(yīng)式表單

在組件的控制器中創(chuàng)建一個(gè)底層的數(shù)據(jù)模型,然后使用一些特定的指令,將模板上的HTML元素與數(shù)據(jù)模型連接起來(lái)。

FormControl

FormGroup

FormArray
可以增長(zhǎng)的自動(dòng)集合

五個(gè)指令

formControl
formControlName
formGroup
formGroupName
formArrayName
指令中后面有name的不能使用屬性綁定語(yǔ)法,也就是不能加[]
當(dāng)formControl和formGroup在一個(gè)嵌套里面,則需要加name

FormBuilder便捷創(chuàng)建數(shù)據(jù)模型

表單驗(yàn)證

angular的校驗(yàn)器

內(nèi)置校驗(yàn)器:Validator
常用的有required, minlength

自定義校驗(yàn)器

校驗(yàn)器名(control:FormControl): any{ return null; }

異步校驗(yàn)器 返回的是一個(gè)可觀測(cè)的流

校驗(yàn)響應(yīng)式表單

判斷模板式表單是否有錯(cuò)誤,可以用hasError方法。第一個(gè)參數(shù)是校驗(yàn)器名,第二個(gè)參數(shù)是校驗(yàn)的屬性。如果是嵌套的屬性,則傳遞一個(gè)數(shù)組,第一個(gè)值是一級(jí)屬性,第二個(gè)值是二級(jí)屬性。

getError方法可以獲取到具體的報(bào)錯(cuò)信息

校驗(yàn)?zāi)0迨奖韱?/h5>

需要把自定義的校驗(yàn)方法封裝為指令,才能在模板中調(diào)用

表單狀態(tài)字段

touched和untouched 判斷字段是否獲取過(guò)焦點(diǎn),用來(lái)控制錯(cuò)誤信息是否顯示

pristine和dirty 判斷字段的值是否修改過(guò)

pending

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容