如何優雅的使用Angular 表單驗證

blank

如何優雅的使用Angular 表單驗證

隨便說說,這一節可以跳過

去年參加ngChine 2018 杭州開發者大會的時候記得有人問我: Worktile 是什麼時候開始使用Angular 的,我說是今年(2018年) 3 月份開始在新模塊中使用最新的Angular 6,他說是不是有點晚了,我當時愣了一下。其實仔細回想了一下, Angular 2.0 正式發布也就在2016-09-14 號,所以也就晚了1 年多一點點才開始使用而已嘛,再加上2.0 到4.0 的過渡或多或少還是有一點點坑的,不是很穩定,此時投入不是特別合適,雖然升級簡單,但是還是有很多概念和API需要重新學習,比如HttpClient,路由等等(在2.0 的時候我們是有嘗試在邊緣的一個Open API Doc 文檔站點使用過的,我們一直在關注著最新的Angular)

所以我覺得4.0 (也就是2017-03)之後的Angular 才真真正正的開始趨於穩定,可以開始嘗試學習和使用,再加上經過了1 年多的社區實踐,踩坑,基礎生態建設,我覺得今年(2018年)才是企業大規模嘗試使用Angular 最佳時間點,再加上Angular CLI 以及@angular/cdk的逐漸強大, 我想說這是一個最好的時代。

另外還有一個原因是2016 - 2017 年屬於我司最艱難的困難時期,壓根沒有心思考慮切換最新技術棧,所以那2 年基本上屬於埋頭做業務。

現在回過頭來看Angular ,在前端框架高速發展的那幾年,因為正式版發布遲遲延期,導致市場被後起之秀React, Vue 等優秀框架佔有,好在新的Angular 足夠優秀,足夠前瞻,值得花更多的時間投入學習和使用,現在還不算晚。所以慢有一定道理的,因為需要精雕玉琢,衡量未來的趨勢等等,但是從完美支持TypeScript,RxJS 這2 點來說,Angular 的確走在了前面。

回歸正題,說到表單,我認為一個強大表單應該包含下面3部分功能

1. 收集用戶輸入的表單數據,在Angular 中通過ngModel 語法糖實現雙向綁定非常方便;

2. 通過各種驗證器驗證表單元素輸入的數據是否合法,Angular 內置了常用的驗證器(required、pattern、email,min,max,minlength,maxlength);

3. 驗證後給予用戶反饋,比如驗證不通過給予錯誤的提示訊息。

我覺得Angular 的表單無疑是三大框架中最強大的,沒有之一,而且是官方原生提供支持和維護,提到Angular 的表單肯定要說下Angular.js 的表單,其實Angular 的表單基本上繼承了Angular.js 表單的所有功能,同時比Angular.js 更強大,API 更友好。

另外說下本文不是普及Angular Form表單的基本知識的,如果有不了解的可以看[angular forms guide]( Angular - Angular表單檢測) ,因為官方文檔已經寫的特別好了。

那麼Angular 的表單和Angular.js 相比到底有哪些改進呢

1.自定義ngModel

在Angular.js 中ng-model 只能用於input,select 等內置的HTML 表單元素,如果是一個自定義的select 框(div),可能就無法使用自帶的required 等驗證器了

但是可以通過猥瑣的方式處理,比如加一個隱藏的原生HTML 表單元素,這個元素上綁定的ng-model 和自定義的select 框的model 是一樣的,然後通過這個隱藏元素是否驗證通過去控制自定義Select 的驗證樣式

那麼在Angular 中可以很方便讓任何自定義的組件使用ngModel 和內置的驗證器,只要你的自定義組件實現ControlValueAccessor 接口,同時在組件的providers 中加上NG_VALUE_ACCESSOR 的provider 即可,具體如何實現一個自定義的支持ngModel組件自行搜索下,官方文檔好像沒有找到相關介紹,附一個stackoverflow question

2.結構型指令內部的表單元素自動識別

在Angular.js 中如果有ng-if 之類的動態指令,內部的表單元素不會自動追加到Form 上,必須通過擴展一個自定義指令`dynamicFormControl ` 去手動追加到ngForm 上,但是在Angular 中不需要用戶自己去處理,只要元素被渲染,會自動附加到ngForm Controls 中。

3.響應式表單

Angular中除了模板驅動表單外,還新增了Angular -響應式表單,讓用戶多了一份選擇,在某些複雜的場景下,響應式表單會更有優勢。

4.動態表單支持更好

在Angular中不管是模板驅動表單還是響應式表單,對於動態創建表單的支持都很好,可以輕鬆的通過[attr.name]="formName"[name]="formName"實現動態表單元素的創建。如果有復雜的驗證器,那麼使用響應式表單會更好。

5.模板驅動表單驗證器支持屬性綁定,動態控制是否需要驗證

如果一個表單元素(比如說用戶名)是否為必填不是確定的,而是動態設置的, 在Angular 中可以通過屬性綁定`[required]="isRequired"` 非常方便的控制,我看了下Angular.js 的源碼現在也是支持的,不知道是我以前沒有發現呢還是之後的版本加上的功能。

6.支持異步驗證器

如果要驗證用戶名輸入是否已經存在,就需要請求API 遠程驗證,那麼這個驗證就是一個異步的,如果驗證器不支持異步就會導致驗證結果沒有返回的時候就直接提交表單了。如果支持異步會更加的完善。

當然Angular 的表單不僅僅只有上述功能,通過我們最近一段時間的使用來看, Angular 表單基本已經完美了,但是

我們還需要讓驗證錯誤提示更加簡單可擴展

回頭再看下開頭的介紹的表單應該包含下面3部分功能

1. 收集用戶的輸入的表單數據; 這個基本上ngModel 雙向綁定的語法糖已經簡化的不能再簡化了,當然使用響應式表單連ngModel 也可以不寫,這塊已經不需要開發者做任何事情了;

2.內置的驗證器滿足大部分場景,但是還是會有很多常用的驗證器官方沒有提供,比如重複驗證,遠程唯一性驗證等等, Nightapes/ngx-validatorsgangachris/ng-validators這2個第三方庫擴展了很多,即使不滿足自己擴展也很簡單;

3. 驗證後給予用戶反饋,驗證不通過給予錯誤的提示訊息。對於這個錯誤提示訊息,每個產品每個用戶都會有不一樣的需求,Angular把可以做到的都做到了,都自動追加了ng-invalidng-validng-touched等class,還有就是哪些元素哪個驗證器驗證失敗都可以從ngModel 和ngForm 方便的獲取到,錯誤提示只能交給用戶自己去處理,如果你的系統僅僅只有樣式的反饋,那就更簡單了。

對於驗證錯誤提示,手動寫錯誤提示的模版會很囉嗦,寫模版本身也沒什麼,怕就怕哪天設計師改需求了,原有的提示方式換了一個新的方式,那整個系統都需要挨個替換,有追求的程序員最怕的就是做重複沒有含量的工作,而且有時候還無法通過批量替換完成,所以在使用Angular.js 1.x的時候我就封裝了一個表單驗證庫why520crazy/angular -w5c-validator ,剛開始發布的時候功能比較簡單,後來有人提各種Issue,逐漸改善,我覺得這個驗證庫對於很多人來說還是有幫助的,至少我覺得是更優雅的處理了各種錯誤提示,star 不多,但是證明了這個封裝還是有一定價值的。

那麼我們即使現在升級到了Angular ,也面臨著錯誤提示如何處理的問題,當然也有些類庫處理了相關問題,但是好像都沒有找到特別好用的。

1. UltimateAngular/ngx-errors還是手寫模版,只是簡化了寫法。

2. NG-ZORRO/ng-zorro-antd組件庫關於表單組件對錯誤驗證提示也做了很多工作,但是還是需要手寫模版配置。

既然沒有相關的類庫符合我們的需求,那麼顯然就需要自己造輪子,所以我們去年在升級Angular時就按照我們的方式在組件庫的Form表單模塊加上了和Angular.js why520crazy/angular-w5c -validator類似的組件,得益於Angular框架的優秀,造起輪子特別簡單。

ngx-validator 已經可以開始使用了

所以這週我單獨抽離了表單驗證功能為一個獨立的類庫why520crazy/ngx-validator ,如果你也在為表單驗證錯誤提示苦惱,也在尋找一種更優雅的錯誤處理方式,希望我的這個庫可以幫助到你或者給你一個啟發。

ngx-validator Demo範例,點擊直接查看演示

blank

最後的最後感謝你耐心閱讀到此,這篇部落格已經計劃了3 個多月了,因為工作繁忙一直沒有時間,這週末下了一個狠心,必須完成!已經被兒子打擾多次,還有就是ngx-validator目前基本的功能已經完成,後期還有很多增強的驗證器,測試需要補充,還不是特別完善,歡迎大家提寶貴意見!開源真不容易,這麼簡單的一個功能花了我周末2天時間寫範例,文檔,反復修改API,然後用蹩腳的英文寫了Readme。

文章來源於Worktile部落格解讀,想了解更多關於企業協作內容可前往查看。

插個廣告,Worktile 2019 年招Angular 前端工程師和Node.js 服務端工程師,歡迎大家加入!

What do you think?

Written by marketer

blank

💯利用Vue原理實現一個mini版的MVVM框架

blank

第二屆螞蟻金服體驗科技大會