AngularJS即时搜索令人难以置信的滞后

时间:2013-02-07 11:54:17

标签: jquery ajax search get angularjs

我目前正在开发一个带有Web前端的数据库。在本项目的先前版本中使用了jQuery之后,我现在开始使用AngularJS进行“即时搜索”功能,如下所示:

function SearchCtrl($scope, $http) {
    $scope.search = function() {  
    $scope.result = null;

    $http({method: 'GET', url: 'api/items/search/' + $scope.keywords }).
        success(function(data, status, headers, config) {
            $scope.result = data;
        }).
        error(function(data, status, headers, config) {
            $scope.status = status;
        });     
    };
}

...
<div id="searchControl" ng-controller="SearchCtrl">
    <form method="get" action="" class="searchForm">
        <input type="text" id="search" name="search" ng-model="keywords" ng-change="search()"/>
        <input type="submit" value="Search" />
    </form>
    <div ng-model="result">
        <a href="javascript:void(0)" ng-repeat="items in result.items" >
            <div class="card">
                <span ng-show="items.id"><b>Item ID: </b>{{items.id}}<br></span>
                <span ng-show="items.part_id"><b>Part ID: </b>{{items.part_id}}<br></span>
                <span ng-show="items.description"><b>Description: </b>{{items.description}}<br></span>
                <span ng-show="items.manufacturer"><b>Manufacturer: </b>{{items.manufacturer}}<br></span>
                <span ng-show="items.product_range"><b>Range: </b>{{items.product_range}}<br></span>
                <span ng-show="items.borrower"><b>Borrower: </b>{{items.borrower}}<br></span>
                <span ng-show="items.end_date"><b>End Date: </b>{{items.end_date}}<br></span>
            </div>
        </a>
    </div>
</div>
...

这很有效,但有一个问题:因为我在“ng-change”上调用搜索功能,因此在输入搜索词时会非常迟钝,有时会使浏览器崩溃。在旧版本(使用jQuery)上,我使用了标志来测试是否有一个get请求已经运行,如果有,那么我在启动新的之前中止了它。我查看了AngularJS文档以了解中止获取请求但仍然没有更明智。如果有人对如何实现这个或其他修复有任何建议我会非常感激。

感谢。

2 个答案:

答案 0 :(得分:2)

一旦发送了get请求,就会发送它。 AFAIK,还没有一种方法来中止处理原生为angular的http请求的结果。这是一个功能请求,当前标记为“OPEN”:https://github.com/angular/angular.js/issues/1159

那就是说,你可以像这样自行中止处理答案:

var currentKey= 0;

$scope.test = function (){
   $http({ method: 'GET', url: 'test.json', key: ++currentKey })
      .success(function(data, status, headers, config) {
         if(config.key == currentKey) {
           //You're now inside your most recent call.
           $scope.foo = data;
         }
      });
};

另一方面,我建议在你的on change事件上实现某种超时,以免它过于“讨厌”。

答案 1 :(得分:0)

angularjs的去抖/限制模型更新将对您的案例有所帮助:http://jsfiddle.net/lgersman/vPsGb/3/

示例中的指令将限制更改事件,以便执行较少的ajax请求。

除了在jsfiddle代码中使用指令之外没有其他事情要做了:

<input 
    type="text" 
    id="search" 
    name="search" 
    ng-model="keywords" 
    ng-change="search()"
    ng-ampere-debounce
/>

它基本上是一小段代码,由一个名为“ng-ampere-debounce”的角度指令组成,利用http://benalman.com/projects/jquery-throttle-debounce-plugin/可以附加到任何dom元素。该指令重新排序附加的事件处理程序,以便它可以控制何时限制事件。

您可以将其用于限制/去抖动 *模型角度更新 *角度事件处理程序ng- [事件] * jquery事件处理程序

看看:http://jsfiddle.net/lgersman/vPsGb/3/

该指令将成为Orangevolt Ampere框架(https://github.com/lgersman/jquery.orangevolt-ampere)的一部分。