Angular JS $优先于ng-change

时间:2013-10-16 08:10:20

标签: angularjs angularjs-directive

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

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

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

问题是如何在$watch中的函数之前对输入的更改执行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] = "";
    }
};

1 个答案:

答案 0 :(得分:2)

一般来说,如果你有两个观察者,D&amp; C既看Z,也最好明确D&amp; D之间的依赖关系。 C,所以你最终不会遇到这些订购问题。

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

  1. 合并

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

    • 您使用$ watch来检查是否相等,但是您依靠事件处理程序来清除错误。为什么不观察密码值和它们的$有效值(或者只是整个输入字段),这样你就可以确保在发生变化时运行检查。
  3. 在我看来,ng-change首先激发是有意义的。它似乎最接近一个事件处理程序,我会在事件发生后立即触发,而你的$ watch只能在下一个$ digest()循环后触发。话虽如此,在这种情况下进行改变和观看游戏可能永远不会是干净的。

    我还不太清楚redisChange函数中的代码是什么。如果你可以使用所有相关位来制作一个jsfiddle,我可能会更有用