如何从AngularJS异步验证器返回错误上下文信息?

时间:2014-11-27 15:37:26

标签: angularjs validation

我正在使用1.3中引入的新AngularJS异步验证器功能。我的指令看起来像这样:

angular.module('app')
    .directive('usernameValidator', function(API_ENDPOINT, $http, $q, _) {
        return {
            require: 'ngModel',
            link: function($scope, element, attrs, ngModel) {
                ngModel.$asyncValidators.username = function(username) {
                    return $http.get(API_ENDPOINT.user, {userName: username})
                        .then(function(response) {
                            var username = response.data;
                            if (_.isEmpty(username)) {
                                return true;
                            } else {
                                return $q.reject(username.error);
                            }
                        }, function() {
                            return $q.reject();
                        });
                };
            }
        };
    });

我想以某种方式将username.error的值放入模型控制器范围中,以便我可以将其显示给用户。显示静态消息很简单,但我想显示服务器返回的一些错误上下文信息。

有没有一种干净的方法可以做到这一点,还是我坚持在模型控制器上设置属性?

编辑:为了澄清,我不是在寻找一个可行的一次性解决方案。我打算将此指令用作可重用,干净地封装的组件。这意味着直接写入周围的范围或类似的东西可能是不可接受的。

3 个答案:

答案 0 :(得分:3)

验证指令就像任何其他指令一样,您可以访问$ scope,所以为什么不设置值:$scope.errors.username = username.error;

angular.module('app')
    .directive('usernameValidator', function(API_ENDPOINT, $http, $q, _) {
        return {
            require: 'ngModel',
            link: function($scope, element, attrs, ngModel) {

                $scope.errors = $scope.errors | {}; //initialize it

                ngModel.$asyncValidators.username = function(username) {
                    return $http.get(API_ENDPOINT.user, {userName: username})
                        .then(function(response) {
                            var username = response.data;
                            if (_.isEmpty(username)) {
                                return true;
                            } else {
                                $scope.errors.username = username.error; //set it here
                                return $q.reject(username.error);
                            }
                        }, function() {
                            return $q.reject();
                        });
                };
            }
        };
    });

我只是单独初始化$scope.errors = $scope.errors | {}; //initialize it,以便您可以在多个指令中重用$scope.errors对象,如果您愿意的话

答案 1 :(得分:0)

为什么没有可以将错误发送到的全局警报数组。

<alert ng-repeat="alert in alerts" type="{{alert.type}}" close="closeAlert($index)"><span ng-class="alert.icon"></span> {{alert.msg}}</alert>

这样做,警报可以是成功或警告或其他。并且可以从全球范围调用。我认为这很好,所以你调用的一个随机位置的异步任务可以向堆栈发出警报。只是一个想法......

答案 2 :(得分:0)

您可以传递一个空变量,并将其设置为reject:

angular.module('app')
.directive('usernameValidator', function(API_ENDPOINT, $http, $q, _) {
    return {
        require: 'ngModel',
        scope: {
            errorMessage: '=usernameValidator'
         },
        link: function($scope, element, attrs, ngModel) {

            ngModel.$asyncValidators.username = function(username) {
                return $http.get(API_ENDPOINT.user, {userName: username})
                    .then(function(response) {
                        var username = response.data;
                        if (_.isEmpty(username)) {
                            return true;
                        } else {
                           //set it here
                            $scope.errorMessage = username.error; 
                            return $q.reject(username.error);
                        }
                    }, function() {
                        return $q.reject();
                    });
            };
        }
    };
});

在你的模板中:

<input
    ng-model="model.email"                  
    username-validation="userValidationError"
    name="email"                                
    type="text">
<p class="error" ng-if="form.email.$error">{{userValidationError}}</p>