父值更改后验证依赖值列表

时间:2017-02-01 22:03:44

标签: angularjs

使用Angular 1.5 +

这是我的情景......我有一个基地,称之为基地'。 然后我得到了一个字段列表,这些字段需要是该基数的倍数,并且我使用$ validator进行简单模数检查。

我可以验证每个单独的字段...因此,如果我在列表中突出显示某个字段并更改其值,则会触发并正确验证。

我需要的是能够改变基地'重视并重新评估所有孩子。我看过很多类似的略有不同的角度问题,但在这种情况下似乎没有任何帮助我。

所以这样的观点:

<div ng-controller="myAppController as app" >
  <input type="text" ng-model="app.base" >
  <br><br>
  are these multiples of above?
  <br><br>
  <div ng-repeat="v in app.values">
    <input type="text" ng-model="v.value" multiple-of="{{app.base}}" />
 </div>

app和控制器是这样的:

  var app = angular.module('myApp', []);
  app.controller('myAppController', function myAppController($filter) {
    var self = this;
    self.base = 10;
    self.values = [
      {value: 10},
      {value: 20},
      {value: 30},
      {value: 40},
      {value: 50}];
  });

使用这样的验证器作为值列表:

  app.directive('multipleOf', function () {
      return {
          require: 'ngModel',
          link: function (scope, elm, attrs, ngModel) {
              ngModel.$validators.multipleOf = function (modelValue, viewValue) {
                  var value = parseInt(modelValue);
                  var base =  parseInt(attrs.multipleOf);
                  var valid = value >= base && value % base === 0;
                  return valid;
              };
          }
      };
  });

在此特定设置中,如果我将base更改为20,则列表值20和40应该验证,但现在其他三个应该无效。如何在基值发生变化时触发此级联验证?

Plunkr:https://plnkr.co/edit/dcc4XFyrPAyLUpT38Dbe?p=preview

2 个答案:

答案 0 :(得分:1)

我已编辑您的plunker以使其正常工作:https://plnkr.co/edit/LW3rRmFSmCdnLUMdqr7Z?p=preview

这不是我写的最好的代码,但它会解释基础知识,因为现在该指令不可重用,因为它应该是预期的;

app.directive('multipleOf', function() {
    return {
      require: 'ngModel',
      link: function(scope, elm, attrs, ngModel) {
        scope.myForm.base.$viewChangeListeners.push(function() {
          scope.myForm.value10.$validate();
          scope.myForm.value20.$validate();
          scope.myForm.value30.$validate();
          scope.myForm.value40.$validate();
          scope.myForm.value50.$validate();
        });
        ngModel.$validators.multipleOf = function(modelValue, viewValue) {
          if (scope.myForm.base.$modelValue && scope.myForm.base.$modelValue >= 0) {
            var value = modelValue || 0;
            var base = parseInt(scope.myForm.base.$modelValue);
            var valid = value >= base && value % base === 0;
            return valid;
          }
        };
      }
    };
  });

但是如果你希望其他字段在更改之后进行验证,则需要添加$ viewChangeListeners。我希望它能解决你的问题。

答案 1 :(得分:0)

找到解决方案......

首先,不要在视图中评估基本表达式,只需将属性作为字符串传递

<div ng-controller="myAppController as app" >
  <input type="text" ng-model="app.base" >
  <br><br>
  are these multiples of above?
  <br><br>
  <div ng-repeat="v in app.values">
    <input type="text" ng-model="v.value" multiple-of="app.base" />
</div>

这允许我们在我们依赖的属性上放置$ watch,我们可以使用scope。$ eval来获取验证器触发时的模型值:

  app.directive('multipleOf', function() {
    return {
      require: 'ngModel',
      link: function(scope, elm, attrs, ngModel) {
        ngModel.$validators.multipleOf = function(modelValue, viewValue) {
            var value = parseInt(modelValue);
            var base = parseInt(scope.$eval(attrs.multipleOf));
            var valid = value >= base && value % base === 0;
            return valid;
        };
        scope.$watch(attrs.multipleOf, function() {
          ngModel.$validate();
        })
      }
    };
  });

修订过的plunkr:https://plnkr.co/edit/9FBhaINpsXW3GxuBgi3E?p=preview