我有一个简单的 HTML5 用户注册表单。验证用户名的值input
以确保没有使用添加到的自定义函数具有相同用户名的用户$asyncValidators
。
考虑以下情况:
- 用户开始输入用户名(例如,“我”)。
- 稍微延迟后,Angular 验证器运行,向服务器发送异步请求,询问用户名是否可用。
- 用户开始输入更多字符(例如,'Me123')。
- 在又一次轻微的延迟之后,Angular 再次尝试通过向服务器发送另一个请求来验证用户名。
当 Angular 收到关于用户名有效性的两个响应时,它会做什么?有没有办法优雅地处理这个问题?
我想做的是以某种方式取消或告诉 Angular 在用户修改用户名值后立即忽略第一次验证尝试的结果。
编辑 2015 年 11 月 12 日:
Sirrocco 的回答帮助我澄清了我的问题。这里有两块:
- 中止实际的 HTTP 请求
- 告诉 Angular 验证过程停止等待返回的承诺
$asyncValidators.usernameAvailable
被解决或拒绝
timeout
我可以通过使用服务选项来做第一个$http
。我的问题是:做第二个是必要的、可取的还是可能的?如果是这样,怎么做?
我认为这可能发生在keyup
添加到指令元素的事件处理程序中link
。见下文:
索引.html
<input
ng-model="user.username"
ng-model-options="{ debounce: 250 }"
check-availability />
checkAvailability.directive.js
function affectsText(keyCode) {
// some code to determine if keyCode could change value of a text input
}
angular
.module('app')
.directive('checkAvailability', ['$q', 'users', function($q, users) {
return {
restrict: 'AC',
require: 'ngModel',
link: function (scope, element, attrs, ctrl) {
element.on('keyup', function(e) {
if (!affectsText(e.keyCode)) {
return;
}
// cancel previous $asyncValidators.usernameAvailable process??
// users service cancels operation by rejecting a promise previously assigned to to $http's timeout option
users.cancelIsAvailableCheck();
});
ctrl.$asyncValidators.usernameAvailable = function(modelValue) {
if (ctrl.$isEmpty(modelValue)) {
return $q.when();
}
var deferred = $q.defer();
users.isAvailable(modelValue).then(function(available) {
if (available) {
deferred.resolve();
} else {
deferred.reject();
}
});
return deferred.promise;
}
}
};
}]);