欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Angular 输入框实现自定义验证功能

程序员文章站 2022-06-24 17:18:00
此插件使用angular.js、jquery实现。(jquery的引入需在angular 之前)   用户可以 在输入框输入数据后验证 必填项、整数型、浮点型验证。  ...

此插件使用angular.js、jquery实现。(jquery的引入需在angular 之前)

  用户可以 在输入框输入数据后验证 必填项、整数型、浮点型验证。

  如果在form 里面的输入框验证,可以点击 提交按钮后,实现 必填项验证。

效果图如下:

Angular 输入框实现自定义验证功能

(1)验证未通过时,背景标红等样式为  

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;
  }

  因为angular.js 内置验证未通过时,会自动为 标签 增加 .ng-invalid 样式,因为这里重写此样式

 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 实现

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);
      }
     }
    });
   }
  }
 }]);

  通过 监听 attrs.ngmodel,验证规则 rules ,ctrl.$parser 来实现 输入框内容改变的响应。

  一旦使用此directive,则动态为当前输入框添加id,以便在 验证通过后,改变输入框的验证背景信息。 

(4)验证逻辑处理 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 === '');
    //如果不是必填项 且没有输入值 则清除提示框
    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) {
      //如果是必填项,有值 返回true
      flag = !isblank;
     } else if (rule.contains(':')) {
      //如果校验规则是 fn:ctrl.certcheck
      flag = this.checkrule(val, rule.split(/:/), $scope, extendparam);
     } else {
      //校验 规则是 int 用正则匹配 数字 邮箱 长度
      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];//指定被调函数的名字 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': '必填',
    'int': '{0}必须为整数'
   }
   ,
   pats: {
    'int': /^[\-\+]?([0-9]+)$/
   }
  }
 }
 ])
 ;

       通过获取输入框 ele.myvalid  验证规则,

   1、如果是必填,则返回 标红此输入框,鼠标移上,则显示 验证信息 “必填””。

   2、如果是整数、浮点型等验证,则通过 正则表达式进行验证。

      3、如果是最大(max)、最小(min),则自定义逻辑。

  4、如果是 fn 验证,则根据 对应controller中函数进行验证。

  5、用户点击提交按钮,则 判断是否必填项,验证不通过,对应元素背景标红。

(5) 验证不通过,提示factory---uitipsfactory

app.factory('uitipsfactory', function () {
  return {
   filterclass: function (ele, invalid) {
    if (invalid) {
     //如果验证不通过
     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、验证不通过,增加背景色,元素css处理如下

 ele.removeclass('ng-valid').removeclass('ng-pristine').addclass('ng-invalid').addclass('ng-dirty');

   验证通过,css处理如下  

 ele.removeclass('ng-invalid').addclass('ng-valid');

 

2、背景提示语,则是在body上增加一个div层。

(6)其他相关代码

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];
  })
 };

   整个代码如下:

<!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 "数字太大了";
     }
     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) {
     //如果验证不通过
     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 === '');
    //如果不是必填项 且没有输入值 则清除提示框
    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) {
      //如果是必填项,有值 返回true
      flag = !isblank;
     } else if (rule.contains(':')) {
      //如果校验规则是 fn:ctrl.certcheck
      flag = this.checkrule(val, rule.split(/:/), $scope, extendparam);
     } else {
      //校验 规则是 int 用正则匹配 数字 邮箱 长度
      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];//指定被调函数的名字 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': '必填',
    'int': '{0}必须为整数'
   }
   ,
   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>