2

我有一个简单的 HTML5 用户注册表单。验证用户名的值input以确保没有使用添加到的自定义函数具有相同用户名的用户$asyncValidators

考虑以下情况:

  1. 用户开始输入用户名(例如,“我”)。
  2. 稍微延迟后,Angular 验证器运行,向服务器发送异步请求,询问用户名是否可用。
  3. 用户开始输入更多字符(例如,'Me123')。
  4. 在又一次轻微的延迟之后,Angular 再次尝试通过向服务器发送另一个请求来验证用户名。

当 Angular 收到关于用户名有效性的两个响应时,它会做什么?有没有办法优雅地处理这个问题?

我想做的是以某种方式取消或告诉 Angular 在用户修改用户名值后立即忽略第一次验证尝试的结果。


编辑 2015 年 11 月 12 日:

Sirrocco 的回答帮助我澄清了我的问题。这里有两块:

  1. 中止实际的 HTTP 请求
  2. 告诉 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;
        }
      }
    };
  }]);
4

1 回答 1

1

最简单的方法是禁用用户输入,例如:

<input 
  name="username"
  ng-model="user.username" 
  ng-model-options="{ updateOn: 'blur' }"
  ng-disabled="myForm.$pending"
  check-availability />

因此,一旦用户退出用户名字段,就会触发验证并禁用该字段(您也可以禁用提交按钮)。

如果这不是可接受的 UX,您可以改用此处描述的方法:http ://www.bennadel.com/blog/2616-aborting-ajax-requests-using-http-and-angularjs.htm

本质上允许在其属性$http上设置一个承诺。timeout如果您resolve使用该属性,则 http 调用将被中止。在验证器中找出最佳方法可能需要一些试验和错误。

于 2015-11-12T06:27:18.237 回答