最近這段時間發現,北京這用angular4 或 angular2的公司不多。幾乎是沒有。很擔憂本身是否是把精力放到了不該該的地方。白耽誤了時間。可是隨着我對新版angular框架理解的加深。我的感受angular4未來會有很大的前景,通用化,組件化,注入服務。用於開發複雜的JS前端應用真是太方便了。而且聽說angular5會更優秀。或許目前的狀況是對新版angular框架研究早了幾年時間吧。前端
這幾天作了修改密碼,用到了自定義指令,驗證新密碼和確認新密碼是否相同。這個是簡單的。全是前端來判斷。網上也有不少例子,百度「angular4 自定義指令「 。會列出不少資料。修改一下就能運行成功。數據庫
當兩個密碼一致後,在去修改新密碼,會顯示以下。服務器
想要簡單一點就是寫兩個自定義驗證指令。一個檢驗新密碼,一個檢驗確認新密碼。不必定向網上那些例子同樣,必定要放到一個驗證指令內。可是更多時候,咱們是要驗證當前輸入數值,是否在服務端對應數據庫內有重複的存在。好比模塊管理頁面上restful
模塊名稱和模塊URl都是不能重複的。底層會經過模塊URl進行頁面定位。因此在進行添加和修改的時候。須要遠程數據校驗,在服務器端進行數據檢測,看看要添加或修改的數值在服務端是否重複存在。這個用angular4的自定義指令來實現。自定義指令都是繼承validate接口。核心是 validate函數。 網絡
validate(c: AbstractControl): { [key: string]: any }
可是validate函數是按鍵觸發,每修改一下數據就執行一次,好比咱們在確認新密碼檢驗治理的validate函數里加上一個輸出,angular2
而後執行下修改密碼操做。這裏爲了顯示方便,我先把input的 type="password" 修改成 type="text" 框架
在確認新密碼那我輸入了9個數字,validate函數就執行了9次。這個機制用來檢驗兩個密碼是否一致是能夠的。可是要檢測遠程數據表中的數據是否有重複。那是絕對不行,每一個字符的修改都要遠程檢測一次,服務端和網絡的壓力會過大。angular4
因此思路應該是用戶在input內輸入的時候咱們不檢測。當input丟失焦點的時候開始檢測。經過http鏈接遠程的restful接口。在遠程數據庫內查詢。按這個思路添加的時候沒問題。可是修改的時候就有問題。好比input內已經有一個數值。input得到焦點,可是不修改任何數值,在讓input丟失焦點。那這時候也會去後臺數據庫檢測一次,可是在後臺就會查出當前input內的數值有一個存在。ide
因此在數據庫檢測的時候要區分爲添加檢測和修改檢測兩種來進行。其實更好的思路是input一獲取焦點,就保存當時value數值。在input丟失焦點的時候在獲取一次value數值。遠程請求前先判斷下兩個數值是否一致。不一致的時候鏈接restful接口進行校驗。因此完整的調用方式以下。函數
checkvalue 是自定義檢驗指令,屬性數值1 或2 是本身擴展的。這個數值傳遞到ssm框架的服務端。用來指明是對那個數據表的那個字段進行是否重複檢驗。這裏多說下,其實更簡單是把服務端數據表名稱和字段名稱直接寫到checkvalue=" " 的屬性數值裏。可是這樣會讓服務端的數據表名稱和字段名稱暴露在前臺。因此我這裏寫了一個數字,傳遞到後臺,用來作索引。更好的索引是傳遞guid。但這裏我就不寫了,之後修改也是很容易。
import { Inject, Input, Directive, forwardRef, Attribute, HostListener } from '@angular/core'; import { Validator, AbstractControl, NG_VALIDATORS } from '@angular/forms'; import { CheckValuePackage } from '../module/common/common'; import { UserNews } from '../module/business/login'; import ConstantsList from '../common/constants/config'; @Directive({ selector: '[checkvalue][formControlName],[checkvalue][formControl],[checkvalue][ngModel]', providers: [ { provide: NG_VALIDATORS, useExisting: CheckValueValidator, multi: true }, ] }) export class CheckValueValidator implements Validator { _v: string; _e: string; _default: string; _openType: number = 0;// 打開方式 0 沒有打開,1 添加打開 , 2 修改打開 _c: AbstractControl constructor( @Attribute('checkvalue') public checkvalue: string, @Attribute('openstate') public openstate: number, @Inject('auxiliary') public auxiliary, @Inject('checkvaildator') public checkvaildator) { } @Input('openstate') set setOpenstate(opentype: number) { this._openType = opentype; }; validate(c: AbstractControl): { [key: string]: any } { this._v = c.value; this._e = this.checkvalue; this._c = c; return null; } @HostListener('blur') //丟失焦點觸發 onblur() { let cv: CheckValuePackage = new CheckValuePackage(); cv.sendvalue = this._v; cv.runtype = this._e; cv.opentype = this._openType; let userNews: UserNews = this.auxiliary.getUserNews(); let sendtoken: string = userNews.id + '-' + userNews.token + '-' + ConstantsList.runid; if (cv.sendvalue !== this._default) { this.checkvaildator.CheckValue(cv, sendtoken).then( ub => { let backCode: number = ub.backCode; switch (backCode) { case -1: this._c.setErrors({ checkvalue: true, message: '遠程驗證發生錯誤' }); break; case 0: this._c.setErrors(null); break; default: this._c.setErrors({ checkvalue: true, message: '此數值後臺已經存在,不可重複' }); break; } } ); } } @HostListener('focus') //獲取焦點觸發 onfocus() { this._default = this._v; } }
寫入已經存在的數值,好比這裏寫入公共模塊的名稱和url。在imput丟失焦點的時候,進行後臺檢測。檢測不經過不可提交
修改數據,打開模塊管理。選擇惟一沒有被鎖定的測試模塊
彈出窗口以下
修更名稱和URl爲已經存在的其餘模塊的數值,這裏咱們仍是把它修改成公用模塊的名稱和url
也會顯示咱們指定的錯誤。這樣咱們就實現了用自定義的angular指令。去後臺進行遠程數據檢測的功能。並且咱們已經把它通用化,組件化了。
具體效果能夠在 http://121.42.203.123 查看。這裏例子上我只修改了模塊管理頁面的添加和編輯。其餘的頁面都沒添加這個遠程驗證。