在ngBlur之后更新了ngModel

时间:2016-05-04 15:00:55

标签: angularjs angular-ui-bootstrap angular-ngmodel onblur

我在AngularJS中使用ui-bootstrap的datepicker输入。它有一个绑定到ngBlur事件的ngModel和validatioon方法:

<input id="startDate" type="text" ng-model="myCtrl.startDate" ng-blur="myCtrl.validateDate()"/>

验证方法根据控制器中的规则集检查ngModel,并在需要时发出警报。这是控制器的相关部分:

var vm = this;
vm.startDate = new Date();
vm.minStartDate = new Date(2000,1,1);
vm.validateDate = function(){
    if(vm.startDate < vm.minStartDate)
        alert("Start date can't be earliar than 2000");
}

问题是,验证方法在更新模型之前运行。示例场景如下:

规则:startDate不能早于 2000 年。 页面加载时,startDate值最初设置为今天。用户从日历中选择 31.12.1999 ,调用ngBlur方法。但是,ngModel尚未更新。因此,验证检查今天的价值并说好。实际上,它应该用 31.12.1999 检查ngModel的值。值在输入视图上同时更改,但在后台,它在模糊方法触发后设置。据我所知,AngularJS中的双向绑定通常用于此目的,但ngBlur必须是例外。

我尝试了很多东西,比如;

  • 将ng-model-options添加到组件中:

    ng-model-options="{ updateOn: 'blur' }"

  • 通过修改输入元素

  • 使用前后链接
  • 使用ng-change而非ng-blur

但是,上述方法均无效,并且在更新模型之前仍会运行ng-blur。

3 个答案:

答案 0 :(得分:0)

我通过手动更新控制器内的值找到了解决方案。显然,AngularJS不会使用HMTL元素内的值更新模型,直到模糊事件被触发。因此,最好编写一个方法来更新它。

我可以按如下方式访问元素内的值:

vm.startDate = angular.element('#startDate').val();

然后我可以用一个方法包装它:

vm.updateModels() = function(){
    vm.startDate = angular.element('#startDate').val();
}

最后,我只是在模糊事件的第一个时调用它:

vm.validateDate = function(){
    //Update first
    vm.updateModels();
    //Then validate
    if(vm.startDate < vm.minStartDate)
        alert("Start date can't be earliar than 2000");
}

Ta tammm,现在我可以验证updatet值了!

答案 1 :(得分:0)

确保仅在更新值后触发验证的一种简单方法是在ng-change而非ng-blur上调用它。这样,您可以确保控制器仅在ng-model值更新后才进行评估。

答案 2 :(得分:0)

尝试构建自己的自定义验证器(指令)

app.directive('integer', function() {
  return {
    require: 'ngModel',
    link: function(scope, elm, attrs, ctrl) {
      ctrl.$validators.integer = function(modelValue, viewValue) {
        if (ctrl.$isEmpty(modelValue)) {
          // consider empty models to be valid
          return true;
        }

        if (INTEGER_REGEXP.test(viewValue)) {
          // it is valid
          return true;
        }

        // it is invalid
        return false;
      };
    }
  };
});

检查此示例 https://plnkr.co/edit/SZoBKakhzIq5wRoCvEyG?p=preview