我有自定义验证的指令(验证用户名尚不存在).验证使用$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>
对于这种情况,Angular有一个专门的$asyncValidators数组:
见https://docs.angularjs.org/api/ng/type/ngModel.NgModelController
ngModel.$asyncValidators.uniqueUsername = function(modelValue,viewValue) { var value = modelValue || viewValue; // Lookup user by username return $http.get({url:'/api/users/' + value}). then(function resolved() { //username exists,this means validation fails return $q.reject('exists'); },function rejected() { //username does not exist,therefore this validation passes return true; }); };