一尘不染

在AngularJS自定义验证指令中调用异步服务

angularjs

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

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;
                        });
                }
            }
        }
    }
]);

这是我的模板:

<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>

阅读 209

收藏
2020-07-04

共1个答案

一尘不染

为了使它起作用,我需要添加“返回值”;在异步调用之外。下面的代码。

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;
                }
            }
        }
    }
]);
2020-07-04