将AngularJS格式化程序和解析器函数放入$ formatters和$ parsers数组时,顺序很重要

时间:2014-02-28 20:27:49

标签: angularjs angularjs-directive

我有以下指令 (摘自使用AngularJS掌握Web应用程序开发一书):

angular.module('unique-email-directive', [])

/**
 * A validation directive to ensure that the model contains a unique email address
 * @param  Users service to provide access to the server's user database
  */
.directive('uniqueEmail', ["Users", function (Users) {
  return {
    require:'ngModel',
    restrict:'A',
    link:function (scope, element, attrs, ngModelCtrl) {
      var original;

      // If the model changes, store this since we assume it is the current value of the user's email
      // and we don't want to check the server if the user re-enters their original email
      ngModelCtrl.$formatters.unshift(function(modelValue) {
        original = modelValue;
        return modelValue;
      });

      // using push() here to run it as the last parser, after we are sure that other validators were run
      ngModelCtrl.$parsers.push(function (viewValue) {
        if (viewValue && viewValue !== original ) {
          Users.query({email:viewValue}, function (users) {
            if (users.length === 0) {
              ngModelCtrl.$setValidity('uniqueEmail', true);
            } else {
              ngModelCtrl.$setValidity('uniqueEmail', false);
            }
          });
          return viewValue;
        }
      });
    }
  };
}]);

我需要澄清是否重要将格式化程序函数放在$ formatters数组的开头,并在结尾处使用解析器函数$ parsers array

如果订单很重要,请解释原因。

1 个答案:

答案 0 :(得分:2)

运行解析器和验证器,以便将返回的值传递给下一个。你只需要决定是否希望你的功能在所有其他功能完成之前运行,或者在所有其他功能完成后才能完成。

来自angularjs docs的

  

每当控件从DOM读取值时,作为管道执行的函数数组。反过来,每个函数都被调用,将值传递给下一个函数。最后一个返回值用于填充模型。用于清理/转换值以及验证。对于验证,解析器应使用$ setValidity()更新有效性状态,并为无效值返回undefined。