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

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

问题描述

我有一个自定义的验证(验证用户名不存在)指令。验证使用$ HTTP服务要求服务器如果用户名存在,所以返回的是一个承诺的对象。这是梦幻般的工作进行验证。形式是无效的,并包含MyForm的。$ error.usernameVerify时的用户名已被使用。然而,user.username永远是不确定的,所以它打破我的NG-模式指令。我想这大概是因为在.success功能是创建它自己的范围和返回值不是在控制器上$范围使用。我该如何解决这个问题所以NG-模型绑定仍然有效?

  commonModule.directive(usernameVerify,[
    userSvc',函数(userSvc){
        返回{
            要求:'ngModel',
            适用范围:假的,
            链接:功能(范围,元素,ATTRS,CTRL){
                CTRL $ parsers.unshift(checkForAvailability)。
                CTRL $ formatters.unshift(checkForAvailability)。                功能checkForAvailability(值){
                    如果(value.length小于5){
                        返回值;
                    }
                    //将userSvc.userExists功能仅仅是一个使用$来休息API调用HTTP
                    userSvc.userExists(值)
                        .success(功能(alreadyUsed){
                            VAR有效= alreadyUsed ===假;
                            如果(有效){
                                CTRL $ setValidity('usernameVerify',真)。
                                返回值;
                            }
                            CTRL $ setValidity('usernameVerify',虚假)。
                            返回不确定的;
                        });
                }
            }
        }
    }
]);

下面是我的模板:

 < D​​IV CLASS =表单组NG-CLASS ={'有错误:accountForm.username $脏放大器;&安培; accountForm.username $无效。 }>
    <标签类=COL-MD-3控制标签>用户名:​​其中; /标签>
    < D​​IV CLASS =COL-MD-9>
        <输入名称=用户名
               TYPE =文本
               类=表格控
               NG-模式=user.username
               NG-禁用=user.id
               NG-= MINLENGTH 5
               用户名 - 验证
               要求/>
        <跨度类=现场验证错误NG秀=$ accountForm.username脏放大器;&安培; accountForm.username $ error.required。>用户名是必需的< / SPAN>
        <跨度类=现场验证错误NG秀=accountForm.username $脏放大器;&安培; accountForm.username $ error.minlength方式>用户名必须至少为5个字符< / SPAN&GT ;
        <跨度类=现场验证错误NG秀=$ accountForm.username脏放大器;&安培; accountForm.username $ error.usernameVerify方式>用户名已采取< / SPAN>
    < / DIV>
< / DIV>


解决方案

在为了得到这个工作,我需要添加返回值;外异步调用的。低于code。

  commonModule.directive(usernameVerify,[
    userSvc',函数(userSvc){
        返回{
            要求:'ngModel',
            适用范围:假的,
            链接:功能(范围,元素,ATTRS,CTRL){
                CTRL $ parsers.unshift(checkForAvailability)。
                CTRL $ formatters.unshift(checkForAvailability)。                功能checkForAvailability(值){
                    如果(value.length小于5){
                        返回值;
                    }
                    userSvc.userExists(值)
                        .success(功能(alreadyUsed){
                            VAR有效= alreadyUsed ===假;
                            如果(有效){
                                CTRL $ setValidity('usernameVerify',真)。
                                返回值;
                            }
                            CTRL $ setValidity('usernameVerify',虚假)。
                            返回不确定的;
                        });
                    //下面是code的补充线。
                    返回值;
                }
            }
        }
    }
]);

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天全站免登陆