English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Implementazione della funzione di validazione personalizzata del campo di input Angular

Questo plugin viene implementato utilizzando angular.js, JQuery (l'introduzione di JQuery deve essere prima di angular).

  L'utente può verificare i campi obbligatori, i campi interi, i campi floating-point dopo aver inserito i dati nel riquadro di input.

  Se si desidera verificare i campi obbligatori all'interno di un form, è possibile effettuare la verifica dei campi obbligatori dopo aver fatto clic sul pulsante di invio.

L'effetto visivo è il seguente:

(1) Gli stili di sfondo rossi e altri quando la verifica non è riuscita sono  

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-shadow: 2px 2px 2px #969696;
   box-shadow: 2px 2px 2px #969696;
  });

  Poiché la verifica integrata di angular.js aggiunge automaticamente lo stile .ng-invalid al tag quando la verifica non è riuscita, perché qui viene sovrascritto questo stile

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

  (2) Il codice HTML è il seguente

<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) Questo plugin utilizza directive myValid per implementare

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;
     validFn(ctrl.$modelValue, oldRules);
    });
    scope.$watch(attrs.ngModel, function (newVal, oldVal) {
     if (newVal === oldVal) {
      return;
     });
     if (ctrl.$modelValue != undefined && (ctrl.$invalid || el.hasClass('ng-invalid'))) {
      validFn(ctrl.$modelValue);
     });
    validFn(ctrl.$modelValue, oldRules);
    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);
   });
  });
 });

  Viene implementata la risposta all'aggiornamento del contenuto dell'input attraverso l'ascolto di attrs.ngModel, regole di verifica, ctrl.$parser.

  Una volta utilizzato questo directive, viene aggiunto dinamicamente un ID all'input corrente per cambiare l'informazione di sfondo di verifica dell'input dopo la verifica riuscita. 

(4) Gestione logica di verifica 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 === '');
    //Se non è un campo obbligatorio e non c'è alcun valore di input, cancella la casella di messaggio
    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) {
      //Se è un campo obbligatorio, ha un valore, restituisce true
      flag = !isBlank;
     } else if (rule.contains(':')) {
      //Se il regolamento di verifica è fn:ctrl.certCheck
      flag = this.checkRule(val, rule.split(/:/), $scope, extendParam);
     else {
      //Verifica: l'規則 è int, usa l'espressione regolare per corrispondere al numero, all'email, alla lunghezza
      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;
      });
     });
     //Cos'è questo?
     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]; // specificare il nome della funzione chiamata certCheck
     var fn = $parse(fnName)($scope);
     if (!fn) {
      return true;
     });
     return fn.call($scope, val, extendParam);
    else {
     return true;
    });
   },
   checkValidForm: function (formName) {
    //只检查必填项
    //使用属性筛选器 获得里面所有的元素
    var formContext = $('form[name="{0}"],[ng-form="{0}"],[data-ng-form="{0}"]'.format(formName)),
      validList = formContext.find('[my-valid]');//validList 不是数组,是伪数组
    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': 'obbligatorio'
    'int': '{0} deve essere un intero'
   });
   ,
   pats: {
    'int': /^[\-\+]?([0-9]+)$/
   });
  });
 });
 })
 ;

       Viene verificato il validatore ele.myValid del riquadro di input attraverso la regola di verifica.

   1、Se è obbligatorio, viene restituito l'evidenziamento del riquadro di input in rosso, quando il mouse si muove sopra, viene visualizzato il messaggio di verifica “obbligatorio”.

   2、Se è una verifica di intero, tipo floating-point e altri, viene effettuata la verifica tramite espressione regolare.

      3、Se è il massimo (max) o il minimo (min), viene utilizzata la logica personalizzata.

  4、Se è una verifica fn, viene effettuata la verifica in base alla funzione del controller corrispondente.

  5、Quando l'utente fa cliccare sul pulsante di invio, viene giudicato se l'elemento è obbligatorio, se la verifica non è riuscita, l'elemento corrispondente viene evidenziato di rosso di sfondo.

(5) La verifica non è riuscita, viene visualizzato l'avviso Factory---uiTipsFactory

app.factory('uiTipsFactory', function () {
  return {
   filterClass: function (ele, invalid) {
    if (invalid) {
     // Se la validazione non è riuscita
     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"
      validFn(ctrl.$modelValue, oldRules);
     else {
      var html = '<div id="vtip_' + id + '" class="vtip qtip qtip-rounded box-shadow-tips">'
        <div class="qtip-content">
      $(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();
     validFn(ctrl.$modelValue, oldRules);
    });
    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');
   });
  });
 validFn(ctrl.$modelValue, oldRules);

   1. La verifica non è riuscita, viene aggiunto il colore di sfondo e il trattamento CSS dell'elemento è come segue

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

   CSS gestito come segue dopo la verifica riuscita  

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

 

2. La descrizione di sfondo è aggiunta come una nuova sezione div nel body.

(6) Altri codici correlati

var app = angular.module('myApp', []);
 app.controller('testCtrl', ['$scope', 'uiValidFactory', function ($scope, uiValidFactory) {
    $scope.certCheck = function (val) {
     if (val > 32) {
      return "数字太大了";
     });
     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];
  })
 });

   Tutto il codice seguente è:

<!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-shadow: 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 "数字太大了";
     });
     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) {
     // Se la validazione non è riuscita
     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"
      validFn(ctrl.$modelValue, oldRules);
     else {
      var html = '<div id="vtip_' + id + '" class="vtip qtip qtip-rounded box-shadow-tips">'
        <div class="qtip-content">
      $(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();
     validFn(ctrl.$modelValue, oldRules);
    });
    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');
   });
  });
 validFn(ctrl.$modelValue, oldRules);
 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 === '');
    //Se non è un campo obbligatorio e non c'è alcun valore di input, cancella la casella di messaggio
    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) {
      //Se è un campo obbligatorio, ha un valore, restituisce true
      flag = !isBlank;
     } else if (rule.contains(':')) {
      //Se il regolamento di verifica è fn:ctrl.certCheck
      flag = this.checkRule(val, rule.split(/:/), $scope, extendParam);
     else {
      //Verifica: l'規則 è int, usa l'espressione regolare per corrispondere al numero, all'email, alla lunghezza
      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;
      });
     });
     //Cos'è questo?
     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]; // specificare il nome della funzione chiamata certCheck
     var fn = $parse(fnName)($scope);
     if (!fn) {
      return true;
     });
     return fn.call($scope, val, extendParam);
    else {
     return true;
    });
   },
   checkValidForm: function (formName) {
    //只检查必填项
    //使用属性筛选器 获得里面所有的元素
    var formContext = $('form[name="{0}"],[ng-form="{0}"],[data-ng-form="{0}"]'.format(formName)),
      validList = formContext.find('[my-valid]');//validList 不是数组,是伪数组
    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': 'obbligatorio'
    'int': '{0} deve essere un intero'
   });
   ,
   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;
     validFn(ctrl.$modelValue, oldRules);
    });
    scope.$watch(attrs.ngModel, function (newVal, oldVal) {
     if (newVal === oldVal) {
      return;
     });
     if (ctrl.$modelValue != undefined && (ctrl.$invalid || el.hasClass('ng-invalid'))) {
      validFn(ctrl.$modelValue);
     });
    validFn(ctrl.$modelValue, oldRules);
    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>

Dichiarazione: il contenuto di questo articolo è stato tratto da Internet, di proprietà dei rispettivi autori, il contenuto è stato contribuito e caricato autonomamente dagli utenti di Internet, questo sito non detiene i diritti di proprietà, non è stato editato manualmente e non assume responsabilità legali correlate. Se trovi contenuti sospetti di violazione del copyright, ti preghiamo di inviare una e-mail a notice#oldtoolbag.com (al momento dell'invio dell'e-mail, sostituisci # con @) per segnalare il problema e fornire prove pertinenti. Una volta verificata, questo sito rimuoverà immediatamente il contenuto sospetto di violazione del copyright.

Ti potrebbe interessare