2

我有一个包含 2 个字段的表单:用户名和密码。
当我的用户名模型更改时,我向 API 发出请求以执行一些检查。

当我以 t 毫秒间隔对工厂进行 x 次调用时$resource,我想知道是否:

  • 在我的控制器中,最后$promise收到的将对应于用户最后一次输入。
  • 之前的承诺将被取消。

我试图找到一种方法来模拟我的 API 调用延迟(因为我在本地工作并且每个响应都是即时的),但我只能找到$http服务示例。

这是一个 jsFiddle 来公开这个案例:http:
//jsfiddle.net/Jfwh9/1/

HTML

<div ng-app="myApp">
    <form ng-controller="loginCtrl">
        Username: {{ username }}
        <br>Password: {{ password }}
        <br>
        <input name="username" placeholder="enter your username" type="text" 
            ng-model="username" ng-change="checkUsername()">

        <input name="password" placeholder="enter your password" type="password" 
            ng-model="password">
    </form>
</div>

应用程序

var myApp = angular.module('myApp', ['ngResource']);

/*
 * PRE-LOGIN
 *
 */
myApp.factory( 'preLogin', ['$resource',
    function( $resource, constants ) {
        // Check if a username exists     
        return $resource( '/api/prelogin', {},
                      {
                          post: {
                              method : 'POST'
                          }
                      });
    }]);


/*
 * Login Controller
 *
 *
 */
myApp.controller('loginCtrl', ['$scope', 'preLogin',
    function( $scope, preLogin ) {
        $scope.username = '';
        $scope.password = '';

        // Do some check on the username...
        $scope.checkUsername = function() {
            console.log('prelogin... ', $scope.username);

            preLogin.post({
                username: $scope.username
            }).$promise.then( function( data ) { // Success
                console.log(data);

            }, function( error ) { // Error
                console.log(error);

            });
        }
    }]);

谢谢!

4

1 回答 1

0

http://jsfiddle.net/5B2U7/1/

myApp.factory( 'preLogin', ['$resource','$q',
function( $resource, $q ) {
    var canceler = $q.defer();

    var cancel = function() {
        canceler.resolve();
        canceler = $q.defer();
    };

    // Check if a username exists     
    // create a resource
    // (we have to re-craete it every time because this is the only
    // way to renew the promise)    
    var initRes = function() {
    cancel();    
    return $resource( '/api/prelogin', {},
                  {
                      post: {
                          method : 'POST',
                          timeout : canceler.promise
                      }
                  });
    };

    return {
        initRes: initRes,
        cancelRes: cancel
    };    
}]);

大致就是您取消先前请求的方式。

但是请记住,即使您在连接建立后取消请求,它也会由服务器执行,在这种情况下,服务器会收到大量无用的请求。这不是一个好习惯。

在您的情况下,使用延迟为 0.5 秒的 $timeout 可能会减少对服务器的不必要调用。大致是这样的:

http://jsfiddle.net/G6uNU/1/

myApp.controller('loginCtrl', ['$scope', 'preLogin','$timeout',
function( $scope, preLogin,$timeout ) {
    var timer = false;
    $scope.username = '';
    $scope.password = '';

    // Do some check on the username...
    $scope.checkUsername = function() {
        console.log('prelogin... ', $scope.username);
        if (timer) {
            $timeout.cancel(timer);
        }
        timer = $timeout(function() {
                preLogin.initRes().post({
                username: $scope.username
            }).$promise.then( function( data ) { // Success
                console.log(data);

            }, function( error ) { // Error
                console.log(error);

            });
        }, 500);

    }
}]);
于 2014-07-25T14:38:20.637 回答