AngularJs验证指令不更新模型

时间:2013-12-10 08:54:43

标签: validation angularjs directive

我做了这个指令来验证一个数字是否在一个范围内:

app.directive('nkNumber', function(){
  return {
    scope: {
      max: '=nkMax',
      min: '=nkMin'
    }, 
    require: 'ngModel', 
    restrict: 'A',
    link: function($scope, iElm, iAttrs, controller) {
      function validate(value){
        if (angular.isDefined(value)){
          value = parseInt(value);
          if ($scope.max){
            var max = parseInt($scope.max);
            controller.$setValidity('nkMax', value < max)
          }
          if ($scope.min){
            var min = parseInt($scope.min);
            controller.$setValidity('nkMin', value > min)
          }
        }
        return value;
      }
      controller.$parsers.push(validate);
      controller.$formatters.push(validate);
    }
  };
});

验证工作正常,但是当我更改输入值时,我的模型不会更新。

为什么会这样?我该如何解决?

1 个答案:

答案 0 :(得分:4)

您可能正在使用1.2.x之前的角度版本。较旧版本的角度处理隔离范围不一致,通常会将其他指令吞入隔离范围。这就是你的情况。

ng-model作用于你的nk-number指令的隔离范围,所以它将它的值写入这个私有范围而不是外部范围。

如果您使用1.2.x版本的角度,隔离范围不会像这样混合,所以事情应该按预期工作。

如果要保留较旧版本的角度,修复程序就是不要对此特定指令使用隔离范围。

通常,除非您的指令具有模板,否则使用隔离范围几乎总是一个坏主意。如果你的指令没有自己的模板,那么使用隔离范围几乎是不合理的,并且可能导致你遇到的那类问题。

以下是没有隔离范围的指令编写示例:

app.directive('nkNumber', function($parse){
  return {
    require: 'ngModel', 
    restrict: 'A',
    link: function($scope, iElm, iAttrs, controller) {

      function validate(value){
        var max = $scope.$eval(iAttrs.nkMax);
        var min =  $scope.$eval(iAttrs.nkMin);

        if (angular.isDefined(value)){
          value = parseInt(value);
          if (max){
            max = parseInt(max);
            controller.$setValidity('nkMax', value < max)
          }
          if ($scope.min){
            min = parseInt(min);
            controller.$setValidity('nkMin', value > min)
          }
        }
        return value;
      }
      controller.$parsers.push(validate);
      controller.$formatters.push(validate);
    }
  };
});

请注意,如果没有隔离范围,您需要在$scope.$eval()nkMax属性上使用nkMin

这实际上是编写此指令的更好方法,并且适用于所有版本的angular。