0

我正在编写一个自定义指令来验证范围内的某些值。它应该像 required 属性一样工作,但不是验证输入文本,而是验证范围内的值。我的问题是这个值是在 $scope.$watch 函数中设置的,这个函数在我的指令之后运行。因此,当我的指令尝试验证尚未设置的值时。是否可以在运行我的自定义指令之前运行 $watch 代码?

这是代码:

var app = angular.module('angularjs-starter', []);

app.controller('MainCtrl', function($scope) {
  var keys = {
    a: {},
    b: {}
  };
  $scope.data = {};

  // I need to execute this before the directive below
  $scope.$watch('data.objectId', function(newValue) {
    $scope.data.object = keys[newValue];
  });
});

app.directive('requiredAttribute', function (){ 
   return {
      require: 'ngModel',
      link: function(scope, elem, attr, ngModel) {
          var requiredAttribute = attr.requiredAttribute;
          ngModel.$parsers.unshift(function (value) {
             ngModel.$setValidity('requiredAttribute', scope[attr.requiredAttribute] != null);
             return value;
          });
      }
   };
});

<input type="text" name="objectId" ng-model="data.objectId" required-attribute="object" />
<span class="invalid" ng-show="myForm.objectId.$error.requiredAttribute">Key "{{data.objectId}}" not found</span>

这是一个笨蛋:http://plnkr.co/edit/S2NrYj2AbxPqDrl5C8kQ?p= preview

谢谢。

4

1 回答 1

1

您可以直接安排$watch在指令链接功能之前发生。你需要改变你的link功能。

link: function(scope, elem, attr, ngModel) {
    var unwatch = scope.$watch(attr.requiredAttribute, function(requiredAttrValue) {
        if (requiredAttribute=== undefined) return;

        unwatch();

        ngModel.$parsers.unshift(function (value) {
            ngModel.$setValidity('requiredAttribute', requiredAttrValue != null);
            return value;
        });
    });
}

这种方法将只激活指令内的 $watch 函数一次,并在第一次设置所需的范围变量时删除观察者。

还有另一种方法可以解析值并以这种方式检查:

link: function(scope, elem, attr, ngModel) {
    var parsedAttr = $parse(attr.requiredAttribute);

    ngModel.$parsers.unshift(function (value) {
        ngModel.$setValidity('requiredAttribute', parsedAttr(scope) != null);
        return value;
    });
}

在这里,您将需要使用$parse AngularJS 服务。这里的区别在于,这会将输入字段标记为无效,而无需等待在所需范围变量上设置的第一个值。

这两种变体都允许您传递表达式而不是简单的变量名。这使得写一些东西成为可能required-attribute="object.var1.var2"

这真的取决于你需要什么。

于 2013-09-18T13:54:35.437 回答