溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Angular如何使用輸入框?qū)崿F(xiàn)自定義驗(yàn)證功能

發(fā)布時(shí)間:2021-07-06 11:31:25 來(lái)源:億速云 閱讀:198 作者:小新 欄目:web開發(fā)

這篇文章將為大家詳細(xì)講解有關(guān)Angular如何使用輸入框?qū)崿F(xiàn)自定義驗(yàn)證功能,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

此插件使用angular.js、JQuery實(shí)現(xiàn)。(jQuery的引入需在angular 之前)

  用戶可以 在輸入框輸入數(shù)據(jù)后驗(yàn)證 必填項(xiàng)、整數(shù)型、浮點(diǎn)型驗(yàn)證。

  如果在form 里面的輸入框驗(yàn)證,可以點(diǎn)擊 提交按鈕后,實(shí)現(xiàn) 必填項(xiàng)驗(yàn)證。

效果圖如下:

Angular如何使用輸入框?qū)崿F(xiàn)自定義驗(yàn)證功能

(1)驗(yàn)證未通過(guò)時(shí),背景標(biāo)紅等樣式為  

input.ng-invalid, select.ng-invalid {
   background-color: #ee82ee !important;
   border: 1px solid #CCC;
  }
  .qtip {
   position: absolute;
   max-width: 260px;
   display: none;
   min-width: 50px;
   font-size: 10.5px;
   line-height: 12px;
   direction: ltr;
  }
  .qtip-content {
   position: relative;
   padding: 5px 9px;
   overflow: hidden;
   text-align: left;
   word-wrap: break-word;
  }
  .qtip-rounded, .qtip-tipsy {
   -moz-border-radius: 5px;
   -webkit-border-radius: 5px;
   border-radius: 5px;
  }
  .qtipmodal-ie6fix {
   position: absolute !important;
  }
  .box-shadow-tips {
   background-color: #F63;
   border-color: #F5A88F;
   color: white;
   -moz-box-shadow: 2px 2px 2px #969696;
   -webkit-box-shaow: 2px 2px 2px #969696;
   box-shadow: 2px 2px 2px #969696;
  }

  因?yàn)閍ngular.js 內(nèi)置驗(yàn)證未通過(guò)時(shí),會(huì)自動(dòng)為 標(biāo)簽 增加 .ng-invalid 樣式,因?yàn)檫@里重寫此樣式

 input.ng-invalid, select.ng-invalid {
   background-color: #ee82ee !important;
   border: 1px solid #CCC;
  } 

  (2)HTML 代碼如下

<body ng-app="myApp">
<form name="baseInfoForm">
 <div ng-controller="testCtrl">
  <input type="text" ng-model="age" my-valid="r"><br>
  <input type="text" ng-model="name" my-valid="int fn:certCheck"><br>
  <input type="button" value="提交" ng-click="submit()">
 </div>
</form>
</body>

(3)此插件使用 directive myValid 實(shí)現(xiàn)

app.directive('myValid', ['$parse', 'uiTipsFactory', 'uiValidFactory', function ($parse, tips, valid) {
  var uiValidAttrIdName = 'ui-valid-id';
  return {
   restrict: 'A',
   require: 'ngModel',
   link: function (scope, el, attrs, ctrl) {
    var validId = el.attr(uiValidAttrIdName);
    if (!validId) {
     validId = Math.guid();
     el.attr(uiValidAttrIdName, validId);
    }
    var getRules = function () {
     return attrs.myValid;
    };
    var lastOldRules;
    var validFn = function (value, oldRules) {
     var sp = '_';
     var rules = getRules();
     var r = valid.check(value, rules, scope, attrs.uiValidTips);
     if (lastOldRules && !oldRules) {
      oldRules = lastOldRules;
     }
     if (r.flag && oldRules) {
      rules = rules ? rules + ' ' + oldRules : oldRules;
     }
     if (rules) {
      var arrInner = rules.split(' ');
      var i = 0;
      for (; i < arrInner.length; i++) {
       var oneRule = arrInner[i];
       if (!oneRule.trim()) {
        continue;
       }
       ctrl.$setValidity(attrs.ngModel + sp + oneRule, r.flag ? true : oneRule != r.rule);
      }
     }
     if (!r.flag) {
      tips.on(el, r.msg);
     } else {
      tips.off(el);
     }
     return r.flag;
    };
    var init = function () {
     var rules = getRules();
     if (!rules) {
      return;
     }
     var parsers = ctrl.$parsers;
     if (parsers && parsers.length > 0) {
      parsers.clean();
     }
     parsers.unshift(function (value) {
      return validFn(value) ? value : undefined;
     });
    };
    scope.$watch(attrs.ngModel, function (newVal, oldVal) {
     if (newVal === oldVal) {
      return;
     }
     if (ctrl.$modelValue != undefined && (ctrl.$invalid || el.hasClass('ng-invalid'))) {
      validFn(ctrl.$modelValue);
     }
    });
    scope.$watch(getRules, function (newRules, oldRules) {
     init();
     lastOldRules = oldRules;
     if (ctrl.$modelValue === undefined || ctrl.$modelValue === null) {
      var needValid = false;
      el.hasClass('ng-invalid');
      var isValNaN = ctrl.$viewValue !== ctrl.$viewValue;
      if (ctrl.$invalid || (ctrl.$viewValue !== undefined && !isValNaN)) {
       needValid = true;
      }
      if (needValid) {
       ctrl.$setViewValue(ctrl.$viewValue);
      }
     } else {
      if (!ctrl.$dirty && attrs.dirtyCheck) {
       console.log('----');
      } else {
       validFn(ctrl.$modelValue, oldRules);
      }
     }
    });
   }
  }
 }]);

  通過(guò) 監(jiān)聽 attrs.ngModel,驗(yàn)證規(guī)則 rules ,ctrl.$parser 來(lái)實(shí)現(xiàn) 輸入框內(nèi)容改變的響應(yīng)。

  一旦使用此directive,則動(dòng)態(tài)為當(dāng)前輸入框添加ID,以便在 驗(yàn)證通過(guò)后,改變輸入框的驗(yàn)證背景信息。 

(4)驗(yàn)證邏輯處理 uiValidFactory

app.factory('uiValidFactory', ['$parse', 'uiTipsFactory', function ($parse, tips) {
  return {
   check: function (val, rules, $scope, defaultTips, extendParam) {
    if (!rules) {
     return {
      flag: true
     };
    }
    var rulesArr = rules.split(' '),
      isBlank = val === null || val === undefined || val === '' || ('' + val === '');
    //如果不是必填項(xiàng) 且沒(méi)有輸入值 則清除提示框
    if ($.inArray('r', rulesArr) === -1 && isBlank) {
     return {
      flag: true
     }
    }
    var i = 0, len = rulesArr.length;
    for (; i < len; i++) {
     var rule = rulesArr[i];
     if (!rule) {
      continue;
     }
     var flag = true;
     if ('r' === rule) {
      //如果是必填項(xiàng),有值 返回true
      flag = !isBlank;
     } else if (rule.contains(':')) {
      //如果校驗(yàn)規(guī)則是 fn:ctrl.certCheck
      flag = this.checkRule(val, rule.split(/:/), $scope, extendParam);
     } else {
      //校驗(yàn) 規(guī)則是 int 用正則匹配 數(shù)字 郵箱 長(zhǎng)度
      var pat = this.pats[rule];
      if (pat instanceof RegExp) {
       if (angular.isString(val)) {
        flag = this.mat(val, pat);
       }
      } else if (angular.isFunction(pat)) {
       flag = pat(val);
      } else {
       flag = false;
      }
     }
     //這是干什么的呢
     if (angular.isString(flag)) {
      return {
       flag: false,
       msg: flag,
       rule: rule
      }
     }
     if (flag === false) {
      var msg = this.getMsg(rule, defaultTips) || this.getMsg('tips.valid');
      console.log(msg);
      return {
       flag: false,
       msg: msg,
       rule: rule
      }
     }
    }
    return {
     flag: true
    }
   },
   checkRule: function (val, ruleArr, $scope, extendParam) {
    //ruleArr fn:certCheck
    var rule = ruleArr[0];
    if (rule === 'fn') {
     fnName = ruleArr[1];//指定被調(diào)函數(shù)的名字 certCheck
     var fn = $parse(fnName)($scope);
     if (!fn) {
      return true;
     }
     return fn.call($scope, val, extendParam);
    } else {
     return true;
    }
   },
   checkValidForm: function (formName) {
    //只檢查必填項(xiàng)
    //使用屬性篩選器 獲得里面所有的元素
    var formContext = $('form[name="{0}"],[ng-form="{0}"],[data-ng-form="{0}"]'.format(formName)),
      validList = formContext.find('[my-valid]');//validList 不是數(shù)組,是偽數(shù)組
    if (!validList.length) {
     return;
    }
    var that = this,
      validFlags = [];
    validList.each(function () {
       var ele = $(this),
         val = ele.val(),
         ruleStr = ele.attr('my-valid');
       if (!ruleStr) {
        return true;
       }
       if (angular.isString(val)) {
        val = val.trim();
       }
       var validRules = ruleStr.split(' ');
       if ($.inArray('r', validRules) != -1 && !val) {
        var modelValue = ele.attr('ng-model') || ele.attr('data-ng-model');
        validFlags.push(modelValue);
        tips.on(ele, that.getMsg('r'));
       }
      }
    );
    return validFlags;
   },
   mat: function (val, pat) {
    if (!pat) {
     return;
    }
    return pat.test(val);
   }
   ,
   getMsg: function (rule, tips) {
    tips = tips || '';
    //可以在界面上直接寫 tips
    if (tips && tips.contains(':')) {
     return tips;
    }
    var msg = this.msgs[rule];
    if (msg) {
     var params0 = tips.contains(':') ? tips.split(/:/)[0] : '';
     var params1 = '';
     if (rule.startsWith('min') || rule.startsWith('max')) {
      var ruleArr = rule.split(/:/);
      params1 = ruleArr[ruleArr.length - 1];
     }
     return msg.format(params0, params1);
    } else {
    }
   }
   ,
   regPat: function (code, pat, msg) {
    if (this.pat[code]) {
     return;
    }
    this.pats[code] = pat;
    this.msgs[code] = msg;
   }
   ,
   msgs: {
    'r': '必填',
    'int': '{0}必須為整數(shù)'
   }
   ,
   pats: {
    'int': /^[\-\+]?([0-9]+)$/
   }
  }
 }
 ])
 ;

       通過(guò)獲取輸入框 ele.myValid  驗(yàn)證規(guī)則,

   1、如果是必填,則返回 標(biāo)紅此輸入框,鼠標(biāo)移上,則顯示 驗(yàn)證信息 “必填””。

   2、如果是整數(shù)、浮點(diǎn)型等驗(yàn)證,則通過(guò) 正則表達(dá)式進(jìn)行驗(yàn)證。

      3、如果是最大(max)、最小(min),則自定義邏輯。

  4、如果是 fn 驗(yàn)證,則根據(jù) 對(duì)應(yīng)controller中函數(shù)進(jìn)行驗(yàn)證。

  5、用戶點(diǎn)擊提交按鈕,則 判斷是否必填項(xiàng),驗(yàn)證不通過(guò),對(duì)應(yīng)元素背景標(biāo)紅。

(5) 驗(yàn)證不通過(guò),提示Factory---uiTipsFactory

app.factory('uiTipsFactory', function () {
  return {
   filterClass: function (ele, invalid) {
    if (invalid) {
     //如果驗(yàn)證不通過(guò)
     ele.removeClass('ng-valid').removeClass('ng-pristine').addClass('ng-invalid').addClass('ng-dirty');
    } else {
     ele.removeClass('ng-invalid').addClass('ng-valid');
    }
   },
   on: function (ele, msg) {
    var lastTip = ele.data('last-tip');
    if (lastTip && lastTip === msg) {
     return;
    }
    ele.data('last-tip', msg);
    this.filterClass(ele, true);
    var offset = ele.offset();
    if (!offset.top && !offset.left && ele.is('hidden')) {
     offset = ele.show().offset();
    }
    var id = ele.attr('ui-valid-id');
    if (!id) {
     id = Math.guid();
     ele.attr('ui-valid-id', id);
    }
    if (id.contains('.')) {
     id = id.replace(/\./g, '_');
    }
    var top = offset.top,
      left = offset.left;
    var getTips = function () {
     var _tip = $('#vtip_' + id);
     if (_tip.length) {
      _tip.html(msg).css({
       'display': 'none',
       'top': top + 'px',
       'left': left + ele.width() + 10 + 'px'
      });
     } else {
      var html = '<div id="vtip_' + id + '" class="vtip qtip qtip-rounded box-shadow-tips">' +
        '<div class="qtip-content">' + msg + '</div>';
      $(html).css({
       'display': 'none',
       'position': 'absolute',
       'top': top + 'px',
       'left': left + ele.width() + 10 + 'px'
      }).appendTo($('body'));
     }
    };
    var bindTipsShow = function () {
     getTips();
     ele.unbind('mouseenter mouseleave').bind('mouseenter', function () {
      var _tip = $('#vtip_' + id);
      if (_tip.is(':hidden')) {
       _tip.show();
      }
     }).bind('mouseleave', function () {
      $('#vtip_' + id).hide();
     });
    };
    bindTipsShow();
   },
   off: function (ele) {
    ele.data('last-tip', '');
    this.filterClass(ele);
    var id = ele.attr('ui-valid-id');
    if (!id) {
     return;
    }
    if (id.contains('.')) {
     id = id.replace(/\./g, '_');
    }
    $('#vtip_' + id).remove();
    ele.unbind('mouseenter mouseleave');
   }
  }
 });

   1、驗(yàn)證不通過(guò),增加背景色,元素css處理如下

 ele.removeClass('ng-valid').removeClass('ng-pristine').addClass('ng-invalid').addClass('ng-dirty');

   驗(yàn)證通過(guò),CSS處理如下  

 ele.removeClass('ng-invalid').addClass('ng-valid');

2、背景提示語(yǔ),則是在body上增加一個(gè)div層。

(6)其他相關(guān)代碼

var app = angular.module('myApp', []);
 app.controller('testCtrl', ['$scope', 'uiValidFactory', function ($scope, uiValidFactory) {
    $scope.certCheck = function (val) {
     if (val > 32) {
      return "數(shù)字太大了";
     }
     return true;
    };
    $scope.submit = function () {
     if (!uiValidFactory.checkValidForm($scope.baseInfoForm.$name)) {
     }
    };
   }]
 );
 Math.guid = function () {
  var a = "", b = 1;
  for (; b <= 32; b++) {
   var c = Math.floor(Math.random() * 16).toString(16);
   a += c;
   if (b === 8 || b === 12 || b === 16 || b === 20) {
    a += '-';
   }
  }
  return a;
 };
 String.prototype.contains = String.prototype.contains || function (a) {
  return this.indexOf(a) != -1;
 };
 String.prototype.format = String.prototype.format || function () {
  var a = Array.prototype.slice.call(arguments);
  return this.replace(/\{(\d+)}/g, function (c, b) {
   return a[b];
  })
 };

   整個(gè)代碼如下:

<!DOCTYPE html>
<html>
<head lang="en">
 <meta charset="UTF-8">
 <title></title>
 <script src="jquery-1.11.1.js"></script>
 <script src="angular.js"></script>
 <style type="text/css">
  input.ng-invalid, select.ng-invalid {
   background-color: #ee82ee !important;
   border: 1px solid #CCC;
  }
  .qtip {
   position: absolute;
   max-width: 260px;
   display: none;
   min-width: 50px;
   font-size: 10.5px;
   line-height: 12px;
   direction: ltr;
  }
  .qtip-content {
   position: relative;
   padding: 5px 9px;
   overflow: hidden;
   text-align: left;
   word-wrap: break-word;
  }
  .qtip-rounded, .qtip-tipsy {
   -moz-border-radius: 5px;
   -webkit-border-radius: 5px;
   border-radius: 5px;
  }
  .qtipmodal-ie6fix {
   position: absolute !important;
  }
  .box-shadow-tips {
   background-color: #F63;
   border-color: #F5A88F;
   color: white;
   -moz-box-shadow: 2px 2px 2px #969696;
   -webkit-box-shaow: 2px 2px 2px #969696;
   box-shadow: 2px 2px 2px #969696;
  }
 </style>
</head>
<body ng-app="myApp">
<form name="baseInfoForm">
 <div ng-controller="testCtrl">
  <input type="text" ng-model="age" my-valid="r"><br>
  <input type="text" ng-model="name" my-valid="int fn:certCheck"><br>
  <input type="button" value="提交" ng-click="submit()">
 </div>
</form>
</body>
<script type="text/javascript">
 var app = angular.module('myApp', []);
 app.controller('testCtrl', ['$scope', 'uiValidFactory', function ($scope, uiValidFactory) {
    $scope.certCheck = function (val) {
     if (val > 32) {
      return "數(shù)字太大了";
     }
     return true;
    };
    $scope.submit = function () {
     if (!uiValidFactory.checkValidForm($scope.baseInfoForm.$name)) {
     }
    };
   }]
 );
 Math.guid = function () {
  var a = "", b = 1;
  for (; b <= 32; b++) {
   var c = Math.floor(Math.random() * 16).toString(16);
   a += c;
   if (b === 8 || b === 12 || b === 16 || b === 20) {
    a += '-';
   }
  }
  return a;
 };
 String.prototype.contains = String.prototype.contains || function (a) {
  return this.indexOf(a) != -1;
 };
 String.prototype.format = String.prototype.format || function () {
  var a = Array.prototype.slice.call(arguments);
  return this.replace(/\{(\d+)}/g, function (c, b) {
   return a[b];
  })
 };
 app.factory('uiTipsFactory', function () {
  return {
   filterClass: function (ele, invalid) {
    if (invalid) {
     //如果驗(yàn)證不通過(guò)
     ele.removeClass('ng-valid').removeClass('ng-pristine').addClass('ng-invalid').addClass('ng-dirty');
    } else {
     ele.removeClass('ng-invalid').addClass('ng-valid');
    }
   },
   on: function (ele, msg) {
    var lastTip = ele.data('last-tip');
    if (lastTip && lastTip === msg) {
     return;
    }
    ele.data('last-tip', msg);
    this.filterClass(ele, true);
    var offset = ele.offset();
    if (!offset.top && !offset.left && ele.is('hidden')) {
     offset = ele.show().offset();
    }
    var id = ele.attr('ui-valid-id');
    if (!id) {
     id = Math.guid();
     ele.attr('ui-valid-id', id);
    }
    if (id.contains('.')) {
     id = id.replace(/\./g, '_');
    }
    var top = offset.top,
      left = offset.left;
    var getTips = function () {
     var _tip = $('#vtip_' + id);
     if (_tip.length) {
      _tip.html(msg).css({
       'display': 'none',
       'top': top + 'px',
       'left': left + ele.width() + 10 + 'px'
      });
     } else {
      var html = '<div id="vtip_' + id + '" class="vtip qtip qtip-rounded box-shadow-tips">' +
        '<div class="qtip-content">' + msg + '</div>';
      $(html).css({
       'display': 'none',
       'position': 'absolute',
       'top': top + 'px',
       'left': left + ele.width() + 10 + 'px'
      }).appendTo($('body'));
     }
    };
    var bindTipsShow = function () {
     getTips();
     ele.unbind('mouseenter mouseleave').bind('mouseenter', function () {
      var _tip = $('#vtip_' + id);
      if (_tip.is(':hidden')) {
       _tip.show();
      }
     }).bind('mouseleave', function () {
      $('#vtip_' + id).hide();
     });
    };
    bindTipsShow();
   },
   off: function (ele) {
    ele.data('last-tip', '');
    this.filterClass(ele);
    var id = ele.attr('ui-valid-id');
    if (!id) {
     return;
    }
    if (id.contains('.')) {
     id = id.replace(/\./g, '_');
    }
    $('#vtip_' + id).remove();
    ele.unbind('mouseenter mouseleave');
   }
  }
 });
 app.factory('uiValidFactory', ['$parse', 'uiTipsFactory', function ($parse, tips) {
  return {
   check: function (val, rules, $scope, defaultTips, extendParam) {
    if (!rules) {
     return {
      flag: true
     };
    }
    var rulesArr = rules.split(' '),
      isBlank = val === null || val === undefined || val === '' || ('' + val === '');
    //如果不是必填項(xiàng) 且沒(méi)有輸入值 則清除提示框
    if ($.inArray('r', rulesArr) === -1 && isBlank) {
     return {
      flag: true
     }
    }
    var i = 0, len = rulesArr.length;
    for (; i < len; i++) {
     var rule = rulesArr[i];
     if (!rule) {
      continue;
     }
     var flag = true;
     if ('r' === rule) {
      //如果是必填項(xiàng),有值 返回true
      flag = !isBlank;
     } else if (rule.contains(':')) {
      //如果校驗(yàn)規(guī)則是 fn:ctrl.certCheck
      flag = this.checkRule(val, rule.split(/:/), $scope, extendParam);
     } else {
      //校驗(yàn) 規(guī)則是 int 用正則匹配 數(shù)字 郵箱 長(zhǎng)度
      var pat = this.pats[rule];
      if (pat instanceof RegExp) {
       if (angular.isString(val)) {
        flag = this.mat(val, pat);
       }
      } else if (angular.isFunction(pat)) {
       flag = pat(val);
      } else {
       flag = false;
      }
     }
     //這是干什么的呢
     if (angular.isString(flag)) {
      return {
       flag: false,
       msg: flag,
       rule: rule
      }
     }
     if (flag === false) {
      var msg = this.getMsg(rule, defaultTips) || this.getMsg('tips.valid');
      console.log(msg);
      return {
       flag: false,
       msg: msg,
       rule: rule
      }
     }
    }
    return {
     flag: true
    }
   },
   checkRule: function (val, ruleArr, $scope, extendParam) {
    //ruleArr fn:certCheck
    var rule = ruleArr[0];
    if (rule === 'fn') {
     fnName = ruleArr[1];//指定被調(diào)函數(shù)的名字 certCheck
     var fn = $parse(fnName)($scope);
     if (!fn) {
      return true;
     }
     return fn.call($scope, val, extendParam);
    } else {
     return true;
    }
   },
   checkValidForm: function (formName) {
    //只檢查必填項(xiàng)
    //使用屬性篩選器 獲得里面所有的元素
    var formContext = $('form[name="{0}"],[ng-form="{0}"],[data-ng-form="{0}"]'.format(formName)),
      validList = formContext.find('[my-valid]');//validList 不是數(shù)組,是偽數(shù)組
    if (!validList.length) {
     return;
    }
    var that = this,
      validFlags = [];
    validList.each(function () {
       var ele = $(this),
         val = ele.val(),
         ruleStr = ele.attr('my-valid');
       if (!ruleStr) {
        return true;
       }
       if (angular.isString(val)) {
        val = val.trim();
       }
       var validRules = ruleStr.split(' ');
       if ($.inArray('r', validRules) != -1 && !val) {
        var modelValue = ele.attr('ng-model') || ele.attr('data-ng-model');
        validFlags.push(modelValue);
        tips.on(ele, that.getMsg('r'));
       }
      }
    );
    return validFlags;
   },
   mat: function (val, pat) {
    if (!pat) {
     return;
    }
    return pat.test(val);
   }
   ,
   getMsg: function (rule, tips) {
    tips = tips || '';
    //可以在界面上直接寫 tips
    if (tips && tips.contains(':')) {
     return tips;
    }
    var msg = this.msgs[rule];
    if (msg) {
     var params0 = tips.contains(':') ? tips.split(/:/)[0] : '';
     var params1 = '';
     if (rule.startsWith('min') || rule.startsWith('max')) {
      var ruleArr = rule.split(/:/);
      params1 = ruleArr[ruleArr.length - 1];
     }
     return msg.format(params0, params1);
    } else {
    }
   }
   ,
   regPat: function (code, pat, msg) {
    if (this.pat[code]) {
     return;
    }
    this.pats[code] = pat;
    this.msgs[code] = msg;
   }
   ,
   msgs: {
    'r': '必填',
    'int': '{0}必須為整數(shù)'
   }
   ,
   pats: {
    'int': /^[\-\+]?([0-9]+)$/
   }
  }
 }
 ])
 ;
 app.directive('myValid', ['$parse', 'uiTipsFactory', 'uiValidFactory', function ($parse, tips, valid) {
  var uiValidAttrIdName = 'ui-valid-id';
  return {
   restrict: 'A',
   require: 'ngModel',
   link: function (scope, el, attrs, ctrl) {
    var validId = el.attr(uiValidAttrIdName);
    if (!validId) {
     validId = Math.guid();
     el.attr(uiValidAttrIdName, validId);
    }
    var getRules = function () {
     return attrs.myValid;
    };
    var lastOldRules;
    var validFn = function (value, oldRules) {
     var sp = '_';
     var rules = getRules();
     var r = valid.check(value, rules, scope, attrs.uiValidTips);
     if (lastOldRules && !oldRules) {
      oldRules = lastOldRules;
     }
     if (r.flag && oldRules) {
      rules = rules ? rules + ' ' + oldRules : oldRules;
     }
     if (rules) {
      var arrInner = rules.split(' ');
      var i = 0;
      for (; i < arrInner.length; i++) {
       var oneRule = arrInner[i];
       if (!oneRule.trim()) {
        continue;
       }
       ctrl.$setValidity(attrs.ngModel + sp + oneRule, r.flag ? true : oneRule != r.rule);
      }
     }
     if (!r.flag) {
      tips.on(el, r.msg);
     } else {
      tips.off(el);
     }
     return r.flag;
    };
    var init = function () {
     var rules = getRules();
     if (!rules) {
      return;
     }
     var parsers = ctrl.$parsers;
     if (parsers && parsers.length > 0) {
      parsers.clean();
     }
     parsers.unshift(function (value) {
      return validFn(value) ? value : undefined;
     });
    };
    scope.$watch(attrs.ngModel, function (newVal, oldVal) {
     if (newVal === oldVal) {
      return;
     }
     if (ctrl.$modelValue != undefined && (ctrl.$invalid || el.hasClass('ng-invalid'))) {
      validFn(ctrl.$modelValue);
     }
    });
    scope.$watch(getRules, function (newRules, oldRules) {
     init();
     lastOldRules = oldRules;
     if (ctrl.$modelValue === undefined || ctrl.$modelValue === null) {
      var needValid = false;
      el.hasClass('ng-invalid');
      var isValNaN = ctrl.$viewValue !== ctrl.$viewValue;
      if (ctrl.$invalid || (ctrl.$viewValue !== undefined && !isValNaN)) {
       needValid = true;
      }
      if (needValid) {
       ctrl.$setViewValue(ctrl.$viewValue);
      }
     } else {
      if (!ctrl.$dirty && attrs.dirtyCheck) {
       console.log('----');
      } else {
       validFn(ctrl.$modelValue, oldRules);
      }
     }
    });
   }
  }
 }]);
</script>
</html>

關(guān)于“Angular如何使用輸入框?qū)崿F(xiàn)自定義驗(yàn)證功能”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI