在AngularJS中提交后验证数据的自定义指令

时间:2014-04-26 16:06:25

标签: angularjs angularjs-directive

我正在尝试使用自定义指令在调用Web服务后验证某些数据。 我在博客上找到了一个示例,但它在表单值的每次更改时调用Web服务!!

我希望只有在用户提交数据时才会调用此自定义指令。

以下是当前代码:

// The directive aims to know if scan.value already exists (HTTP Response 2xx) or not (HTTP 404) in the database.
.directive('ensureExists', ['$http',
                             function($http) {
  return {
    require: 'ngModel',
    link: function(scope, elem, attrs, ctrl) {
      $http({
        method: 'GET',
        url: 'http://www.toto.com/api/' + scope.scan.value
      }).success(function(data, status, headers, cfg) {
        ctrl.$setValidity('exists', true);
      }).error(function(data, status, headers, cfg) {
        ctrl.$setValidity('exists', false);
      });
    }
  }
}]);

在HTML中:

<input type="number"
    name="cardid"
    required
    ng-model="scan.value"
    ng-focus <!-- Another custom directive that make simple data type validation -->
    ensure-Exists
    />

目前,我觉得一旦表单加载就会调用代码,因为我有一个错误,因为scope.scan.value未定义。

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

您提交的用于主动验证的文章,这就是它立即触发的原因。您正在寻找的是一个指令,等待它被指示这样做之前进行验证。您可以从控制器或服务广播事件并在您的指令中响应它们,或者您只需让指令在父控制器上监视范围变量,直到它的计算结果为true,然后执行您需要它执行的操作。

等待来自父控制器的信号的指令的

Here's a very plain example

你可以将它与你的结合:

.directive('ensureExists', ['$http',
                             function($http) {
  return {
    require: 'ngModel',
    scope: {
      checkValidity: '&ensureExists',
      scan: '=ensureExistsScan'
    },
    link: function(scope, elem, attrs, ctrl) {
       function check() {
          $http({
             method: 'GET',
             url: 'http://www.toto.com/api/' + scope.scan.value
           }).success(function(data, status, headers, cfg) {
             ctrl.$setValidity('exists', true);
           }).error(function(data, status, headers, cfg) {
             ctrl.$setValidity('exists', false);
           });
       }

       scope.$watch(function() { return scope.checkValidity(); }, function(newValue, oldValue) {
           // only check if the value transitioned from false to true
           if (newValue === true && !oldValue) check();
      });          
    }
  };
}]);

模板中的用法(假设scan是父控制器范围内的值):

<input ... ensure-exists="ccnumberExists" ensure-exists-scan="scan" />

然后您需要做的就是将指令属性设置为父控制器上的作用域值,就像在我的第一个示例中一样,当您希望它启动检查时(例如在您提交内容之后),只需设置该范围值为true