在此推薦本身開發的一款基於 Angular Material 的中後臺管理框架。
Github: https://github.com/ng-matero/ng-matero
預覽地址: https://ng-matero.github.io/ng-matero/
我不是 Angular 的佈道者,但現在自稱 Angular 派,使用 Angular 作項目讓我有一種興奮感。目前的三大主流前端框架都研究過,博客中也有三者的相關教程,最先接觸的是 React,可是並無實際的項目經驗,只作過一些 Demo 。使用 Vue 作過一個比較複雜的移動端大數據項目,技術棧採用 Framework7 + Vue + Vuex,總體效果仍是滿意的。css
由於去年的項目幾乎都是後臺管理系統,因此框架用的很少,主要仍是傳統方式開發,後期爲了改善前端開發體驗,逐步在向框架靠攏。經過第三方 Bootstrap 框架對比發現,大多都有 Angular 版本,並且組件庫是最全的,React 和 Vue 版本的組件庫相對匱乏一些。事實證實使用 Angular 開發大型後臺管理系統具備獨特的優點。另外一方面, Angular 是困難度複雜度的一個縮影,它匯聚了設計模式、設計哲學、工程化思想,對於前端開發是質的飛越。 除此以外,Angular 的文檔讓我着迷,除了基本的教程以外,其核心知識是最讓我津津樂道的地方,不只能夠了解技術內幕,甚至能夠學習不少基本知識,都很是實用,對於前端新手以及業餘愛好者都有很大的幫助做用。html
使用 Angular 開發須要很是多的前置知識,好比 TypeScript、RxJS 等,因此學習成本比較高,這也是不少人望而卻步的一方面。在通過很長時間的學習及準備以後,終於在今年有了項目實戰的機會,項目很小,是整個系統中的一個獨立模塊,可是幾乎全部知識都有涉獵,可謂「麻雀雖小五臟俱全」。本文就是對該項目的一些總結及思考。前端
開發環境的搭建很是簡單,使用 Angular CLI 幾乎能夠完成全部工做,可是在與後端聯調接口的時候,還須要作一些自定義配置。如下是 proxy.config.json
文件的基本設置:react
{ "/api": { "target": "http://localhost:3000", "secure": false } }
Angular CLI 的使用貫穿整個項目,從開發到打包無處不在,這也是 Angular 工程化的體現。由於 CLI 的參數很是多,必須仔細閱讀文檔,合理設置參數,全部的需求幾乎都能在參數中找到。其中使用 ng build
打包後可能會有資源引用錯誤的問題,能夠看一下使用 ng build 構建後資源地址引用錯誤的問題。git
在聯調接口時,可能還會遇到傳輸 Cookie 的問題,具體能夠參見 關於 Angular 跨域請求攜帶 Cookie 的問題。github
由於項目比較小,開發之初打算本身寫組件,好比分頁,但實際狀況比較複雜,尤爲剛接觸 Angular,對於組件交互、異步數據還有點懵,嘗試寫了一下,仍然有不少問題,因此最終仍是選擇比較成熟的 UI 庫。面試
UI 庫的選擇須要根據樣式決定,好比個人項目使用的是 Bootstrap,因此 UI 庫選擇了和 Bootstrap 相關的 ngx-bootstrap。對於後臺管理系統,經常使用的組件無外乎彈窗、分頁、標籤頁等。對於更復雜的系統,也能夠根據本身的狀況選擇其餘組件更豐富的 UI 庫,好比 PrimeNG 等。ajax
組件庫主要使用了彈窗及分頁,其中 ngx-bootstrap 的彈窗是一個比價優秀的組件,信息輸入及提示都會用到。如下是一個自定義 Alert 彈窗,經過 Service 共享組件便可。編程
modal-alert.component.html
中的代碼是整個組件的 HTML 結構,有兩個變量及一個實例方法。json
<div class="modal-header"> <h4 class="modal-title pull-left">{{title}}</h4> <button type="button" class="close pull-right" aria-label="Close" (click)="bsModalRef.hide()"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> {{content}} </div> <div class="modal-footer"> <button type="button" class="btn btn-default" (click)="bsModalRef.hide()">關閉</button> </div>
在 modal-alert.component.ts
中定義變量及組件實例。
import { Component, OnInit } from '@angular/core'; import { BsModalRef } from 'ngx-bootstrap/modal/bs-modal-ref.service'; @Component({ selector: 'app-modal-alert', templateUrl: './modal-alert.component.html', styleUrls: ['./modal-alert.component.css'] }) export class ModalAlertComponent implements OnInit { title: string; content: string; constructor(public bsModalRef: BsModalRef) {} ngOnInit() { } }
在 modal.service.ts
中定義了組件的公共方法 modalAlert()
。
export class ModalService { modalRef: BsModalRef; constructor(private modalService: BsModalService, private http: HttpClient) { } modalAlert(msg: string) { const initialState = { content: msg, title: '提示信息' }; this.modalRef = this.modalService.show(ModalAlertComponent, { initialState: initialState, class: 'modal-sm' } ); } }
最後還須要在 app.module.ts
中定義 entryComponents
,好比:
@NgModule({ declarations: [ ... ], imports: [ ... ], ... entryComponents: [ModalAlertComponent, ModalConfirmComponent] })
還有一點須要注意,在使用模板引用變量時,不要和函數名重名,有時圖省事可能會忽略這一點。好比如下代碼會報錯:
<ng-template #Alert> ... <div class="modal-footer"> <button type="button" class="btn btn-primary" (click)="Alert()">肯定</button> </div> </ng-template>
Angular 提供了兩種表單,模板驅動表單及響應式表單。其中模板驅動表單簡單靈活,適用於不復雜的表單數據。
關於表單這一塊,咱們將 Angular 和 Vue 放在一塊兒說,Vue 的表單綁定就屬於模板驅動表單。不過 Angular 的模板驅動表單並無複選框的多選綁定,若是有這個需求,能夠選擇更加靈活強大的響應式表單進行數據綁定。其實,對於數組形式的數據可使用自然的 select 多選框實現。好比如下代碼:
<div class="form-group"> <label for="power">Hero Power</label> <select class="form-control" id="power" multiple required [(ngModel)]="model.power" name="power"> <option *ngFor="let pow of powers" [value]="pow">{{pow}}</option> </select> </div>
關於數組類型的數據,在 Vue 中有兩種綁定方法,分別是複選框及 select 多選框。然而複選框的 value
值只有 true
或者 false
,而 select 多選框的 value
值就是數組。因此 Vue 對複選框的多選操做進行了處理,而 Angular 沒有,須要你本身處理。經過 Angular 的響應式表單能夠很容易實現。可是對於模板驅動表單也能夠用另類的方式實現,好比手動實現一個雙向數據綁定,雖然有點麻煩,但倒是可行的。關於這個話題我放到下一篇文章中說明。
官方文檔中關於表單的內容很是詳細,從用戶輸入到綁定再到校驗,比着葫蘆畫瓢就能夠輕鬆實現雙向數據綁定。我很是喜歡 Angular 中 [()]
(盒子裏的香蕉)這種數據綁定方式,經過閱讀官方文檔的核心知識,對於雙向數據綁定的認識有了質的提升。
管道的用處很是大,就我我的而言,時間轉換及數據映射比較常見。我主要想討論一下數據映射的問題。起初打算本身寫關於數據映射的管道,可是想了想,難道不一樣的數據映射都單獨寫一個管道?而後我就想有沒有自帶的管道實現數據映射,仔細翻了翻文檔,最後終於找到了,I18nPluralPipe
就是用於映射數據的。咱們用一個最多見的數據映射例子說明,好比保存性別數據時,1 表示男,2 表示女。
@Component({ selector: 'i18n-plural-pipe', template: `<div>{{ sex | i18nPlural: sexMapping }}</div>` }) export class I18nPluralPipeComponent { sex: string = '1'; sexMapping: {[k: string]: string} = {'=1': '男', '=2': '女', 'other': '其餘'}; }
I18nPluralPipe
使用了 ICU 格式,確實長見識了。這個管道真的很好用,至少不用對每個數據映射都寫一個專用管道了。
上方示例代碼中, sexMapping
使用接口中的可索引的類型進行定義。
關於 RxJS 是一個比較複雜的話題,我也沒有徹底弄明白。Angular 官網的定義以下:
響應式編程是一種面向數據流和變動傳播的異步編程範式( Wikipedia)。RxJS(響應式擴展的 JavaScript 版)是一個使用可觀察對象進行響應式編程的庫,它讓組合異步代碼和基於回調的代碼變得更簡單 ( RxJS Docs)。
關於異步開發的歷史在面試中有遇到過,能夠說的東西不少,好比回調函數、Promise、迭代器和生成器、aysnc 和 await,除此以外,RxJS 中的可觀察對象(Observable)應該是下一個更強大的異步編程方式。Angular 官網對可觀察對象(Observable)和承諾(Promise)進行了對比。
須要特別注意的就是,只有當訂閱 Observable
的實例時,它纔會開始發佈值。 訂閱時要先調用該實例的 subscribe()
方法,並把一個觀察者對象傳給它,用來接收通知。我剛開始使用時,也是由於這個緣由被坑了一把。如下是一個很簡單的官方示例:
import { ajax } from 'rxjs/ajax'; // 建立一個發送 AJAX 請求的 Observable 對象 const apiData = ajax('/api/data'); // 訂閱請求 apiData.subscribe(res => console.log(res.status, res.response));
這個簡單的小項目用了大約一週多的時間,Angular 算是入門了,關於 Angular 還有很是多值得深究的知識。總體而言,Angular + TypeScript 的開發方式很是舒服,VSCode 對 TS 的支持很是完美,語法提示、自動補全都很方便,強類型語言是前端開發的趨勢。使用 Angular 開發,正如我文章開頭提到的同樣,不只僅是學習一個框架,而是學習一種思想,瞭解更加優秀的開發模式、開源項目,可讓本身始終站在技術的前沿,這是我最大的收穫。
若是你們喜歡 Angular 或者對 Angular Material 感興趣,歡迎進羣討論!