如何从其他指令控制表单的有效性

How to control form validity from other directives

本文关键字:表单 有效性 控制 指令 其他      更新时间:2023-09-26

我的表单是:

<form name="regForm" novalidate>
        <div class="form-group has-feedback" form-validation>
            <label class="control-label">Username</label>
            <div ensure-unique="{{user.username}}">
                <input type="text" class="form-control" name="username"
                       ng-model="user.username"
                       required
                       ng-minlength="3" />
            </div>
 </div>
</form>

ensure-unique指令中,我正在检查用户名是否被采用,在这种情况下,如果使用用户名,我想将我的用户名字段设置为无效。我怎么能做到这一点,如果我不想应用确保唯一的指令到<input>元素?因为我想隔离这个指令的作用域,并使用ng-transclude。当我应用于输入元素时,ng-transclude不起作用。

你可以需要一个父窗体控制器,然后通过输入的名称获得相应的ngModel控制器,如formCtrl['username']:

return {
  restrict: 'A',
  scope: {
    isPending: '=',
  },
  require: '^form',
  link: function (scope, element, attrs, formCtrl) {
    var modelCtrl = formCtrl[attrs.ensureUnique];
    if (!modelCtrl) { return; }
    var counter = 0;
    scope.isPending = false;
    var validator = function (value) {
      modelCtrl.$setValidity('unique', false);
      scope.isPending = true;
      var currentCount = ++counter;
      checkUnique(value).then(function (isUnique) {
        if (currentCount !== counter) { return; }
        modelCtrl.$setValidity('unique', isUnique);
        scope.isPending = false;
      });
      return value;
    };
    modelCtrl.$parsers.push(validator);
    modelCtrl.$formatters.push(validator);
  }
};

例子: http://jsbin.com/cequp/18/edit

我将通过在input元素中添加另一个指令来修改ensure-unique指令在其编译函数中的跨包内容。类似于'nameToCheck'指令,它被设置为user.username

nameToCheck指令会"要求"ng-model,并在它的link函数中导入ng-model的控制器。在link函数中,检查用户名是否唯一:如果不是唯一,则设置有效性标志:

scope: true,
require: 'ngModel',
link: function(scope, element, attr, ngModelController) {
      var username = scope.$eval(attr.nameToCheck);
      if (// username taken //) {
          ngModelController.$setValidity('unique', false);
      }
      else { 
          ngModelController.$setValidity('unique', true);
      }
});