本篇主要簡單了解學習完angular官網內容后查看簡書中優質文章后,補充了解更多有關angular重要知識點及技巧
學習前人學習angular心得。
架構概覽圖:
此圖來大概表示下 Angular 的架構概覽,基本涉及到一些常見的重要的知識點
*對于 Angular 來說,這些都是一份份的 ts 文件代碼,所以,都需要在相對應的文件中加上一些裝飾器比如:@Directive,@Pipe,@Component,@NgModel 等這些,才能夠讓 Angular 識別出該文件的角色、用途。
模塊
一個 Angular 項目,至少會有一個模塊,即最少都會有一份用 @NgModel 聲明的 ts 文件,表明該文件作為模塊角色,來管理其他角色。
其他角色包括:組件、指令、管道、服務等等,這些角色必須在模塊文件中聲明了,才能夠被該模塊內的其他角色所使用,而且同一個組件、指令、管道不允許同時在多個模塊中進行聲明,只能通過模塊 exports 給其他模塊使用。
Angular 里的模塊,不僅可以在項目結構上集中管理同一個模塊的代碼文件,還可以為模塊內的代碼提供一個運行的上下文。
意思就是說,不同模塊在運行期間互不影響,就好像各自運行在各自的沙箱容器中一樣。舉個簡單的例子,在不同模塊中聲明相同的變量名,或相同的 css 的類選擇器,它們之間并不會起沖突。
當然,模塊之間可以有交互,模塊可以依賴于另一模塊,模塊內的可以共享資源等等,所以,NgModel 中有許多需要配置的聲明項,比如:
- declarations:聲明屬于本模塊內的組件、指令、管道
- providers:聲明屬于本模塊內的服務
- imports:聲明本模塊所引用的其他模塊,通常是 imports 其他模塊在 exports 中聲明的項
- exports:聲明本模塊對外公開的組件、指令、管道等,在這里公開的項才可以被其他模塊所使用
- bootstrap:只有根模塊才需要配置,用來設置應用主視圖,Angular 應用啟動后,這里就是入口,類似于 Android 中的入口 Activity
- 還有其他一些可選配置,比如應用主題,或者動態的組件聲明等等
在 Angular 中,大多數的模式就是,一個根模塊管理著很多功能模塊,然后,每個模塊管理自己模塊內部所使用到的組件、指令、管道、服務、或者需要依賴于其他模塊,如果該模塊內部的這些角色,有些可以供其他模塊使用,那么就需要對外暴露。
路由
Angular 并不會一開始就把所有模塊都加載,而是惰性加載,按需加載。
組件是什么時候會被使用: 一是組件被直接調用;二是觸發了路由去加載;
頁面的跳轉,通常有以下幾種場景:
- 用戶輸入 url 進行跳轉
- 用戶點擊交互按鈕進行跳轉
- 用戶操作前進或后退進行跳轉
組件與模板
組件可以是你在界面上看到的任何東西,可以是一個頁面,可以是頁面上的一個按鈕。
對于瀏覽器解析并呈現前端頁面時,Html、CSS、JavaScript 這三分文件通常都是需要的,而 Angular 是使用了 TypeScript,所以一個組件,其實就包括了:Html,CSS,TypeScript。
在 Angular 中,可以說,是以組件為單位來組成頁面的,組件是核心,因為 Angular 提供的功能基本都是用來為組件服務的。
但要注意,官網教程中,很多地方的組件描述,更多時候是傾向于表示 TypeScript 的那份文件,因為對于組件來說,TypeScript 可以說是它的核心,CSS 只是樣式文件,Html 更類似于模板存在。
所以這里將組件和模板放在一起講,因為就像開頭那張圖一樣,組件是一份 TypeScript 文件,在該文件中,定義了這個組件的模板(template)來源和 CSS 樣式來源。
模板提供了該組件的呈現結構,而 TypeScript 里定義了組件的數據來源及交互行為,它們兩一起組織成一個視圖呈現給用戶。
既然,這份 TypeScript 的組件文件和模板文件需要共同合作,那么它們之間就少不了交互,所以就涉及到很多所謂的模板語法,也就是所謂的組件和模板之間的交互方式。
比如,當要往模板中嵌入 TypeScript 中的變量數據時,可以使用 {{value}} 這種語法形式,同樣的,還有模板中標簽的屬性綁定,事件回調注冊的交互方式的語法。
總之,Angular 支持雙向數據綁定,是一種以數據驅動的思想來讓頁面進行交互刷新的方式,區別于傳統的前端模式。在以往,如果需要動態的更新 DOM 上的信息時,需要先獲取到相對應的元素實例對象,然后調用相應的 DOM API 來操縱 DOM;
而使用 Angular 的話,可以直接在模板的相應元素中,將某個屬性與 TypeScript 文件中某個變量直接進行綁定,后續這個變量值變化時,Angular 會自動去更新相應 DOM 的屬性,也就是說,原本那些操縱 DOM 的代碼,Angular 幫我們做了,我們不用再自己去處理了。
另外,注意,以上出現的 TypeScript 的描述,你可以理解成官網中的組件,我之所以不想用組件的方式來進行描述,是因為,我覺得,組件是一個整體,它本身就包括了 TypeScript 文件和模板文件,所以官網中說的組件和模板的交互,我覺得,換成組件中的 TypeScript 文件與模板文件的交互更為適合。
服務
服務是一個廣義上的概念,通常用來處理那些跟 UI 交互無關的事情,比如網絡請求的工作等。
指令
指令也是為組件服務的,但是,是在組件的模板文件中來使用.
因為組件的模板,其實就是一份 HTML 文件,基于 HTML 的標簽之上,加上一些 Angular 的模板語法,而 Angular 在將這份 HTML 文件代碼交給瀏覽器解析之前,會先自行解析一遍,去將模板中不屬于 HTML 的那些語法解析出相應的行為。
而指令分為結構型指令和屬性型指令,它們的區別,其實就在于,一個是改變 DOM 的結構,一個是改變 DOM 元素的樣式。
所以說,指令的目的,其實就是簡化一些操縱 DOM 的工作,比如你需要讓某些按鈕都具有統一的行為和樣式,當被點擊時先做什么,再做什么。
實現這個,你當然可以在 TypeScript 中去書寫這些邏輯,但要應用到每個按鈕上,就比較繁瑣。
這個時候,就可以將這些工作都封裝到指令內部,然后在每個按鈕標簽上加上該指令,Angular 在解析模板時,發現了這個指令,就會為每個按鈕都加上這么一段程序邏輯。
當然,上面舉的場景,也可以自己封裝個按鈕組件,然后在其他模板中,不使用原生按鈕,而使用封裝后的按鈕組件,也可以達到目的。
所以,組件其實也是指令的一種,但組件的實現方式會比較重,有時候,只需要封裝一些簡單的行為邏輯,就可以直接借助指令的方式封裝。
指令的原理也很簡單,在模板中某個元素標簽上,添加上某個指令后,解析到這個指令時,會進入這個指令的相關工作,而指令內部,會獲取到一個當前指令掛載的元素標簽對象,既然都拿到這個對象了,那么,在指令內部想對這個元素做什么,都可以了。
指令還有另一個通途,通常用來擴展原有的功能,因為可能項目中,在模板里使用的組件或者 HTML 元素的標簽因為種種原生無權或不方便進行修改,而又想在其基礎上擴展一些功能,此時就可以利用指令來實現。
管道
管道同樣是為組件服務,也同樣是在組件的模板文件中來使用。
它的用途,在于,將數據按照一定的規則進行轉換,比如 Object 對象,轉換成 json 格式數據,再比如,long 型的時間,轉換成具體的時間日期等等。
Angular 中已經內置了一些管道,也可以自定義管道。
angular.json
這是 Angular-CLI 的配置文件,而 Angular-CLI 是自動化的工程構建工具,也就是利用這個工具,可以幫助我們完成很多工作,比如創建項目、創建文件、構建、打包等等。
原本的 HTML、CSS、JavaScript 的前端開發模式,并沒有工程的概念,只要用瀏覽器打開 HTML 文件就能夠運行。而 Angular 引入了 TypeScript,Scss 等瀏覽器并不無法識別的語言,自然,要讓瀏覽器運行 Angular 項目之前,需要進行一次編譯,一次轉換。
這些工作就可以借助 Angular-CLI 來進行。另外,創建一個模塊,創建一個組件,也都可以通過 Angular-CLI 來。
那么,在創建這些文件或者說,打包編譯這些項目文件時,該按照怎樣的規則,就是參照 angular.json 這份配置文件。
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json", // 默認的配置項,比如默認配置了 ng g component 生成組件時應該生成哪些文件等等
"version": 1,
"newProjectRoot": "projects",
"projects": {
"daView": { // 項目的配置
"root": "",
"sourceRoot": "src", // 源代碼路基
"projectType": "application", // 項目的類型,是應用還是三方庫(library)
"prefix": "app", // 利用命令生成 component 和 directive 的前綴
"schematics": {}, // 替換掉第一行的 schema.json 中的一些默認配置項,不如創建組件時,不要生成spec文件
"architect": { // 執行一些構造工作時的配置
"build": { // 執行 ng build 時的一些配置項
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/daView", // 編譯后的文件輸出的位置
"index": "src/index.html", // 構建所需的模板 Index.html
"main": "src/main.ts", // 構建所需的文件
"polyfills": "src/polyfills.ts", // 構建所需的文件
"tsConfig": "src/tsconfig.app.json", // 對 typescript 編譯的配置文件
"assets": [ // 構建所需的資源
"src/favicon.ico",
"src/assets"
],
"styles": [ // 構建所需的樣式文件,可以是 scss
"src/styles.css"
],
"scripts": [] // 構建所需的三方庫,比如 jQuery
},
"configurations": {/*...*/}
},
"serve": {/*...*/}, // 執行 ng serve 時的一些配置項
"extract-i18n": {/*...*/},
"test": {/*...*/},
"lint": {/*...*/}
}
}
},
"daView-e2e": {/*...*/},
"defaultProject": "daView"
}
所以,利用 Angular-CLI 生成的初始項目中,有許多基本的文件,這些文件,基本也都在 angular.json 中被配置使用了,每個配置文件基本都有各自的用途。
比如,tslint 用來配置 lint 檢查,tsconfig 用來配置 TypeScript 的編譯配置,其他那些 html,css,ts,js 文件基本都是 Angular 項目運行所需的基礎文件。
package.json
在 Angular 項目中,是使用 npm 來進行三方庫的管理,對應的配置文件就是 package.json。
在這份配置文件中,配置了項目所需要的三方庫,npm 會自動去將這些三方庫下載到 node_modules 目錄中。然后,再去將一些需要一起打包的三方庫在 angular.json 中進行配置
Angular-CLI 命令
命令
別名
說明
generate
g
創建相應的文件,如組件、指令、管道、服務、模塊、路由、實體類等
build
b
編譯項目,并輸出最后的文件到指定目錄,可以配置很多參數來達到各種效果,比如實時更新等目的
server
s
編譯項目,并讓它運行起來,且默認支持實時更新修改
new
n
創建新項目,生成項目初始骨架,默認包括根模塊、根視圖,還有基本的各種配置文件
e2e
e
編譯并運行項目,跑起來后,運行 e2e 測試
lint
l
對項目進行 lint 檢查
test
t
運行單元測試
help
查看命令的幫助信息
...
...
還有一些沒用過,也不大清楚的命令,后續再補充