检查在AngularJS中完成的任何正在进行的后台API调用

时间:2013-08-30 08:21:17

标签: angularjs watch restangular

我的AngularJS控制器正在调用API来获取成员列表。可以使用多个过滤器查询API,例如年龄范围,名称搜索,邮政编码等。

我想要完成的是让用户觉得搜索速度非常快。因此,当用户进行过滤时,我正在观察更改过滤器。当过滤器更改时,我会立即执行新的搜索API调用,而不是等待用户单击“搜索”。

这个想法是当用户完成过滤并点击“搜索”时,系统应该已经完成​​搜索并且只能输出搜索结果。

问题:当用户点击“搜索”并调用publish()函数时,我必须确保当前没有正在进行的API搜索,如果是,请等待它完成。然后,我将搜索结果从隐藏的memberslist.temp发布到可见的memberslist.members

// Current code works, except the publish function. See the TODO:

app.controller('SearchCtrl', ['$scope', 'Restangular', '$timeout', function($scope, Restangular, $timeout) {

    // Pushes prefetched search results over to the visible search results
    // TODO: Check if search is ongoing...
    $scope.publish = function() {
        $scope.memberslist.members = $scope.memberslist.temp;
    };

    // Watch filters for changes
    var searchTimer    = false;
    var previousSearch = [$scope.name, $scope.minAge, $scope.maxAge];

    $scope.$watch('[name, minAge, maxAge]', function(newVal, oldVal, scope){
        if (searchTimer) {
            $timeout.cancel(searchTimer);
        }  

        // Do search only after the user has stopped typing for 400 ms
        searchTimer = $timeout(function(){
            if (!_.isEqual(newVal, previousSearch)) {
                previousSearch = newVal;
                scope.search();
            }
        }, 400);
    }, true);

    $scope.search = function() {
        var query_params = {
            name:        $scope.name, 
            price_min:   $scope.minAge,
            price_max:   $scope.maxAge
        };

        Restangular.all('members').getList(query_params)
            .then(function(members){
                $scope.memberslist.temp = members;
            });
    };
}]);

我的第一个想法是设置一个像isSearching = true的变量,然后在搜索调用返回结果后将其设置为false。似乎无法让它工作。

1 个答案:

答案 0 :(得分:1)

也许是这样的:

$scope.$watch('!is_searching && publishing', function(newVal){
  if (newVal) {
    $scope.memberslist.members = $scope.memberslist.temp;
    $scope.publishing = false;
  }
})

搜索开始时在范围内将“is_searching”设置为true,并在完成后将其设置为false。单击搜索按钮时,在范围上设置“发布”。

这应该会给你想要的行为。如果没有搜索正在运行,立即发布,否则请等到搜索完成。