在 AngularJS 自定义验证指令中调用异步服务 [英] Call async service in AngularJS custom validation directive

查看:18
本文介绍了在 AngularJS 自定义验证指令中调用异步服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义验证指令(验证用户名不存在).验证使用 $http 服务询问服务器用户名是否存在,因此返回的是一个 promise 对象.这对于验证非常有效.当用户名已被使用时,表单无效并且包含 myform.$error.usernameVerify.但是, user.username 始终未定义,因此它破坏了我的 ng-model 指令.我认为这可能是因为 .success 中的函数正在创建它自己的范围,并且返回值未在控制器 $scope 上使用.我该如何解决这个问题,以便 ng-model 绑定仍然有效?

commonModule.directive("usernameVerify", ['userSvc',函数(userSvc){返回 {要求:'ngModel',范围:假,链接:函数(范围,元素,属性,ctrl){ctrl.$parsers.unshift(checkForAvailability);ctrl.$formatters.unshift(checkForAvailability);函数 checkForAvailability(value) {if (value.length <5) {返回值;}//userSvc.userExists 函数只是使用 $http 调用 rest apiuserSvc.userExists(值).成功(功能(已使用){var valid = alreadyUsed === 'false';如果(有效){ctrl.$setValidity('usernameVerify', true);返回值;}ctrl.$setValidity('usernameVerify', false);返回未定义;});}}}}]);

这是我的模板:

<div class="form-group" ng-class="{'has-error': accountForm.username.$dirty && accountForm.username.$invalid}"><label class=" col-md-3 control-label">用户名:</label><div class="col-md-9"><输入名称=用户名"类型=文本"类=形式控制"ng-model="user.username"ng-disabled="user.id"ng-minlength=5用户名验证需要/><span class="field-validation-error" ng-show="accountForm.username.$dirty && accountForm.username.$error.required">需要用户名.</span><span class="field-validation-error" ng-show="accountForm.username.$dirty && accountForm.username.$error.minlength">用户名必须至少为 5 个字符.</span><span class="field-validation-error" ng-show="accountForm.username.$dirty && accountForm.username.$error.usernameVerify">用户名已被占用.</span>

解决方案

为了让它起作用,我需要添加返回值;"在异步调用之外.代码如下.

commonModule.directive("usernameVerify", ['userSvc',函数(userSvc){返回 {要求:'ngModel',范围:假,链接:函数(范围,元素,属性,ctrl){ctrl.$parsers.unshift(checkForAvailability);ctrl.$formatters.unshift(checkForAvailability);函数 checkForAvailability(value) {if (value.length <5) {返回值;}userSvc.userExists(值).成功(功能(已使用){var valid = alreadyUsed === 'false';如果(有效){ctrl.$setValidity('usernameVerify', true);返回值;}ctrl.$setValidity('usernameVerify', false);返回未定义;});//下面是添加的代码行.返回值;}}}}]);

I have a directive for custom validation (verify a username doesn't already exist). The validation uses the $http service to ask the server if the username exists, so the return is a promise object. This is working fantastic for validation. The form is invalid and contains the myform.$error.usernameVerify when the username is already taken. However, user.username is always undefined, so it's breaking my ng-model directive. I think this is probably because the function in .success is creating it's own scope and the return value isn't used on the controllers $scope. How do I fix this so the ng-model binding still works?

commonModule.directive("usernameVerify", [
    'userSvc', function(userSvc) {
        return {
            require: 'ngModel',
            scope: false,
            link: function(scope, element, attrs, ctrl) {
                ctrl.$parsers.unshift(checkForAvailability);
                ctrl.$formatters.unshift(checkForAvailability);

                function checkForAvailability(value) {
                    if (value.length < 5) {
                        return value;
                    }
                    // the userSvc.userExists function is just a call to a rest api using $http
                    userSvc.userExists(value)
                        .success(function(alreadyUsed) {
                            var valid = alreadyUsed === 'false';
                            if (valid) {
                                ctrl.$setValidity('usernameVerify', true);
                                return value;
                            } 
                            ctrl.$setValidity('usernameVerify', false);
                            return undefined;
                        });
                }
            }
        }
    }
]);

Here is my template:

<div class="form-group" ng-class="{'has-error': accountForm.username.$dirty && accountForm.username.$invalid}">
    <label class=" col-md-3 control-label">Username:</label>
    <div class="col-md-9">
        <input name="username"
               type="text"
               class="form-control"
               ng-model="user.username"
               ng-disabled="user.id"
               ng-minlength=5
               username-verify
               required />
        <span class="field-validation-error" ng-show="accountForm.username.$dirty && accountForm.username.$error.required">Username is required.</span>
        <span class="field-validation-error" ng-show="accountForm.username.$dirty && accountForm.username.$error.minlength">Username must be at least 5 characters.</span>
        <span class="field-validation-error" ng-show="accountForm.username.$dirty && accountForm.username.$error.usernameVerify">Username already taken.</span>
    </div>
</div>

解决方案

In order to get this to work, I needed to add "return value;" outside of the asynchronous call. Code below.

commonModule.directive("usernameVerify", [
    'userSvc', function(userSvc) {
        return {
            require: 'ngModel',
            scope: false,
            link: function(scope, element, attrs, ctrl) {
                ctrl.$parsers.unshift(checkForAvailability);
                ctrl.$formatters.unshift(checkForAvailability);

                function checkForAvailability(value) {
                    if (value.length < 5) {
                        return value;
                    }
                    userSvc.userExists(value)
                        .success(function(alreadyUsed) {
                            var valid = alreadyUsed === 'false';
                            if (valid) {
                                ctrl.$setValidity('usernameVerify', true);
                                return value;
                            }
                            ctrl.$setValidity('usernameVerify', false);
                            return undefined;
                        });
                    // Below is the added line of code.
                    return value;
                }
            }
        }
    }
]);

这篇关于在 AngularJS 自定义验证指令中调用异步服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆