ngModel。$ setValidity只能运行一次

时间:2017-02-03 16:52:07

标签: angularjs twitter-bootstrap validation angularjs-directive datepicker

我正在进行角度bootstrap ui datepicker弹出验证,问题是我可以设置最大最小日期并验证(仅当用户通过点击日历设置日期时),但是用户手写日期验证是无用的,我为此做了一个指令,但只验证并设置错误一次,这是我的标记

<div class="form-group clearfix">
  <div class="col-md-3 m-t-b-20">
    <label>Date validation</label>
    <p class="input-group col-md-12">

      <input id="validationDate"
             type="text"
             name="validationDate"
             class="form-control"
             uib-datepicker-popup="{{ Ctrl.format }}"
             data-ng-model="Ctrl.formObj.validationDate"
             is-open="Ctrl.validationDate.opened"
             datepicker-options="Ctrl.dateOptions"
             ng-required="true"
             close-text="Close"
             placeholder="Fecha de radicacion"
             ng-click="Ctrl.openDatePicker('validationDate')"
             required
             date-validate/>

      <span class="input-group-btn">
        <button type="button"
                class="btn btn-default"
                ng-click="Ctrl.openDatePicker('validationDate')"
                data-ng-disabled="Ctrl.blockFields">
          <i class="glyphicon glyphicon-calendar"></i>
        </button>
      </span>

    </p>

    <!-- THE ERROR TO SHOW -->
    <p data-ng-show="stepOne.validationDate.$error.validbound"
       class="text-red">
      the selected date exeeds the max and min date boundaries
    </p>
  </div>

这是我的指示

var dateValidate = function () {
    return {
      require: 'ngModel',
      link: function (scope, elem, attr, ngModel) {

        elem.bind('keyup', function(value) {

            var atrvls = scope.$eval(attr.datepickerOptions),
                maxDate = moment(atrvls.maxDate, 'DD/MM/YYYY'),
                minDate = moment(atrvls.minDate, 'DD/MM/YYYY'),
                cDate = moment(elem.val(), 'DD/MM/YYYY', true);

            ngModel.$setValidity('validbound', true);

            if (!cDate.isValid()) {
                return false;
            }

            if (!cDate.isBetween(minDate, maxDate)) {
                ngModel.$setValidity('validbound', false);
            }

        });

    }
};

};

我想知道为什么验证只是第一次进行,而后面的指令什么都不做

2 个答案:

答案 0 :(得分:0)

在链接功能中 - 使用自定义验证创建验证功能,您可以在ngModel上添加$ watch。$ viewValue

scope.$watch(function () {
             return ngModel.$viewValue;
         }, validate);

而不是&#39; Keyup&#39;我认为&#39;模糊&#39;会更好。

答案 1 :(得分:0)

这里有几件事。

首先,时刻isBetween()中给出的日期是排他性的,而datePicker&#39; minDatemaxDate是包含日期。因此,您希望传递其他参数以包含范围内的这些最小和最大日期:

cDate.isBetween(minDate, maxDate, null, '[]')

其次,如果您正在寻找关于日期是否在该范围内的即时反馈,那么您需要将$setValidity包裹在scope.$apply函数中。

没有查看Datepicker弹出窗口的javascript,我无法确切地说出为什么需要它,但是从实验中我可以看到它只在弹出窗口关闭时应用ng-invalid-validbound属性(而{只要有效性设置为true,就会应用{1}}。我认为这是性能方式,因为无论如何都无法使用弹出窗口选择越界日期,您只能采用其他方式 - 从无效日期到使用弹出窗口选择有效日期。

这或多或少是我做的:

ng-valid-validbound

这里是一名掠夺者:http://plnkr.co/edit/toXpEWNa99o7Gfs69KfZ?p=preview