2

我正在使用 Angular JS 制作注册表单,其中一个函数 ,regisChange()通过ng-change.

我有另一个名为的自定义指令equals,用于$watch检查密码字段并用于ngModel.$setValidity('equals', password1==password2)设置表单的有效性。

理想情况下,每当用户更改他的密码字段时,我都希望该equals指令在ng-change. 这样可以在引用它equals之前设置表单的有效性。ng-change

问题是如何$watch在函数 in 之前对输入的更改执行 a ng-change

HTML

  <div class="form-group">
    <label for="register-password1">Password</label>
    <input name="password1" type="password" class="form-control" ng-model="user.password1" required ng-minlength="6" ng-maxlength="20" equals="{{user.password2}}" ng-blur="fieldValidate('password1')" ng-change="regisChange('password1')">
    <div class="error">{{error.password1}}</div>
  </div>

  <div class="form-group">
    <label for="register-password2">Confirm Password</label>
    <input name="password2" type="password" class="form-control" ng-model="user.password2" required equals="{{user.password1}}" ng-blur="fieldValidate('password2')" ng-change="regisChange('password2')">
    <div class="error">{{error.password2}}</div>
  </div>

等于指令

welcome.directive('equals', [function(){
  return {
    restrict: 'A', // only activate on element attribute
    require: 'ngModel', // get a hold of NgModelController
    link: function(scope, elem, attrs, ngModel) {
      if(!ngModel) return; // do nothing if no ng-model

      // watch own value and re-validate on change
      scope.$watch(attrs.ngModel, function() {
        validate();
      });

      // observe the other value and re-validate on change
      attrs.$observe('equals', function (val) {
        validate();
      });

      var validate = function() {
        // values
        var val1 = ngModel.$viewValue;
        var val2 = attrs.equals;

        // set validity
        console.log('val1: '+val1)
        console.log('val2: '+val2)
        ngModel.$setValidity('equals', val1 === val2);
      };
    }
  }
}]);

控制器中的 regisChange()

$scope.regisChange = function(fieldName){
    console.log($scope.regisForm["password2"].$valid);
    if($scope.regisForm[fieldName].$valid){
      $scope.error[fieldName] = "";
    }
};
4

1 回答 1

2

一般来说,如果您有两个观察者 D 和 C 都观察 Z,最好明确说明 D 和 C 之间的依赖关系,这样您就不会遇到这些排序问题。

我不确定是否可以保证 $watch 和其他数据绑定事件的顺序。但是你可以做一些事情。

  1. 巩固

    • 将您的有效性计算移到您的 regisChange 函数中,而不是使用您的自定义指令。在您只检查几个值的这些简单情况下,这将很容易。这将消除您的 equal 指令的 $watch 处理程序触发和 ng-change 调用 regisChange 之间的竞争条件。
  2. 始终如一

    • 您使用 $watch 来检查是否相等,但随后您依靠事件处理程序来清除错误。为什么不 $watch 密码值和它们的 $valid 值(或只是整个输入字段),这样您就可以确保在发生变化时运行检查。

在我看来,ng-change 首先触发是有道理的。它似乎最类似于一个事件处理程序,我认为它会在事件发生后立即触发,而您的 $watch 只能在下一个 $digest() 循环之后触发。话虽如此,在这种情况下,让 ng-change 和 $watch 像你希望的那样玩可能永远不会干净。

无论如何,我不太确定代码在 redisChange 函数中试图做什么。如果您可以使用所有相关位制作一个 jsfiddle,我可能会更有用

于 2013-10-18T05:34:23.610 回答