Angular4 后台管理系統搭建(9) - 用自定義angular指令,實現在服務端驗證


    最近這段時間發現,北京這用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。但這里我就不寫了,以后修改也是很容易。

[openstate]="this.openType" 是一個可綁定的擴展。自動獲取open的模態窗台是添加還是編輯。
 
<p *ngIf="mname.errors" style="color:red">{{ mname.errors.message}}</p> 是用來顯示自定義錯誤信息的 。調用方式就介紹完。
 
checkvalue的檢測類如下:
 
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   查看。這里例子上我只修改了模塊管理頁面的添加和編輯。其他的頁面都沒添加這個遠程驗證。

 

  

 

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM