简体   繁体   中英

AngularJS Instant Search Incredibly Laggy

I'm currently working on a database with a web front-end. Having used jQuery for the previous versions of this project, I've now moved to using AngularJS for the "instant-search" feature like this:

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>
...

This works great but with one issue: because I'm calling the search function on "ng-change" it is extremely laggy when typing a search term, sometimes crashing the browser. On the old version (using jQuery) I had used flags to test if there was a get request already running and if there was then I aborted it before starting the new one. I've looked at the AngularJS documentation for aborting get requests but am still none the wiser. If anyone has got any advice on how to achieve this or another fix I'd greatly appreciate it.

Thanks.

Well once the get request is sent, it's sent. AFAIK, there's not yet a way to abort processing the result of an http request native to angular. Here's a feature request that is currently labelled as "OPEN": https://github.com/angular/angular.js/issues/1159

That said, you can abort the processing of the response yourself like this:

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 the flip side of that, I'd recommend implementing a timeout of some sort on your on change event, to keep it from being too "chatty".

Debounced / throttled model updates for angularjs will be helpful in your case : http://jsfiddle.net/lgersman/vPsGb/3/

The directive from the example will throttle change events so that lesser ajax requests will be executed.

There is nothing more to do than using the directive in the jsfiddle code like this:

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

Its basically a small piece of code consisting of a single angular directive named "ng-ampere-debounce" utilizing http://benalman.com/projects/jquery-throttle-debounce-plugin/ which can be attached to any dom element. The directive reorders the attached event handlers so that it can control when to throttle events.

You can use it for throttling/debouncing * model angular updates * angular event handler ng-[event] * jquery event handlers

Have a look : http://jsfiddle.net/lgersman/vPsGb/3/

The directive will be part of the Orangevolt Ampere framework ( https://github.com/lgersman/jquery.orangevolt-ampere ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM