最近這段時間發現,北京這用angular4 或 angular2的公司很少。幾乎是沒有。很擔心自己是不是把精力放到了不應該的地方。白耽誤了時間。但是隨着我對新版angular框架理解的加深。個人感覺angular4將來會有很大的前景,通用化,組件化,注入服務。用於開發復雜的JS前端應用真是太方便了。並且據說angular5會更優秀。或許目前的情況是對新版angular框架研究早了幾年時間吧。
這幾天做了修改密碼,用到了自定義指令,驗證新密碼和確認新密碼是否相同。這個是簡單的。全是前端來判斷。網上也有很多例子,百度“angular4 自定義指令“ 。會列出很多資料。修改一下就能運行成功。
當兩個密碼一致后,在去修改新密碼,會顯示如下。
想要簡單一點就是寫兩個自定義驗證指令。一個檢驗新密碼,一個檢驗確認新密碼。不一定向網上那些例子一樣,一定要放到一個驗證指令內。但是更多時候,我們是要驗證當前輸入數值,是否在服務端對應數據庫內有重復的存在。比如模塊管理頁面上
模塊名稱和模塊URl都是不能重復的。底層會通過模塊URl進行頁面定位。所以在進行添加和修改的時候。需要遠程數據校驗,在服務器端進行數據檢測,看看要添加或修改的數值在服務端是否重復存在。這個用angular4的自定義指令來實現。自定義指令都是繼承validate接口。核心是 validate函數。
validate(c: AbstractControl): { [key: string]: any }
但是validate函數是按鍵觸發,每修改一下數據就執行一次,比如我們在確認新密碼檢驗治理的validate函數里加上一個輸出,
然后執行下修改密碼操作。這里為了顯示方便,我先把input的 type="password" 修改為 type="text"
在確認新密碼那我輸入了9個數字,validate函數就執行了9次。這個機制用來檢驗兩個密碼是否一致是可以的。但是要檢測遠程數據表中的數據是否有重復。那是絕對不行,每個字符的修改都要遠程檢測一次,服務端和網絡的壓力會過大。
所以思路應該是用戶在input內輸入的時候我們不檢測。當input丟失焦點的時候開始檢測。通過http連接遠程的restful接口。在遠程數據庫內查詢。按這個思路添加的時候沒問題。但是修改的時候就有問題。比如input內已經有一個數值。input獲得焦點,但是不修改任何數值,在讓input丟失焦點。那這時候也會去后台數據庫檢測一次,但是在后台就會查出當前input內的數值有一個存在。
所以在數據庫檢測的時候要區分為添加檢測和修改檢測兩種來進行。其實更好的思路是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 查看。這里例子上我只修改了模塊管理頁面的添加和編輯。其他的頁面都沒添加這個遠程驗證。