2016-07-30 55 views
0

我已經爲我的角度js應用程序實現了自定義搜索功能。在角度js中處理多個Ajax調用搜索功能

爲此,我調用了一個Ajax請求來獲取數據。 這個調用發生在change事件上,這就是爲什麼它會多次調用我的Ajax。

請建議,因爲我是新的角js。

+0

你正面臨的確切問題是......?你介意分享一些代碼嗎? – CozyAzure

+0

我的問題是:說我寫了一些東西,然後快速擦除它,然後在後端,已經發生了Ajax調用,這會在成功後帶來一些結果。 –

回答

2

您可以考慮延遲(空閒時間)。假設我在搜索文本框中輸入如果我空閒了200ms,400ms或任何你想要的時間,你可以調用一個AJAX請求。

如果我輸入salman,它會調用6次API。但假設我們會有空閒時間。我們將在用戶空閒時調用該特定時間。

要實現它的角度,你可以使用。 $ watch或bootstrap指令

2

所以你最好的選擇是給自己一點點延遲。正如阿卡什指出的,你必須選擇你認爲可以接受的延遲時間。您還需要確保請求僅在延遲之後進行。

下面是做到這一點的一種方法:

//In your controller 
var _timeout; 

$scope.fetchSearchResults = function(){ 

    //We will clear the previous timeout because a key has been pressed 
    clearTimeout(_timeout); 

    //Set the timeout - if no key is pressed, it will execute. Else the line above will clear it. 
    _timeout = setTimeout(function(){ 
     var keyword = $scope.searchKeyword.name; 
     //Do your AJAX request here 


     //We have delayed the request by 400ms - but you can change it as you please. 
    }, 400); 
} 

你的HTML:

<!-- Then in your HTML something similar to: --> 
<input ng-model="searchKeyword.name" ng-keyup="fetchSearchResults()" /> 

編輯:

如果你想要去的 '純' 的角度來說,你'd是這樣做的:

//In your controller 
//NOTE: make sure you've injected $timeout into your controller 
var _timeout; 

$scope.fetchSearchResults = function(){ 

    //We will clear the previous timeout because a key has been pressed 
    $timeout.cancel(_timeout); 

    //Set the timeout - if no key is pressed, it will execute. Else the line above will clear it. 
    _timeout = $timeout(function(){ 
     var keyword = $scope.searchKeyword.name; 
     //Do your AJAX request here 


     //We have delayed the request by 400ms - but you can change it as you please. 
    }, 400); 
} 
+0

這就是我如何爲我的搜索做反擊:)任何你使用'setTimeout'而不是角的'$ timeout'服務的原因? – plong0

+0

我只是想保持簡單而不添加$超時DI等,但是,我修改了我的答案。謝謝! –

1

我絕對推薦@ jeanpaul的「debouncing」的答案。

除此之外,當您有多個併發AJAX請求的潛力並且您想要處理最近的請求時,可能需要驗證它在響應處理程序中的哪個請求。 (即前一個請求花費的時間比以後的一個迴應)時的響應並不總是進來,他們被要求以相同的順序

一個解決這種方式,這一點尤其重要的是一樣的東西:

var activeRequest; 
function doRequest(params){ 
    // reqId is the id for the request being made in this function call 
    var reqId = angular.toJson(params); // I usually md5 hash this 

    // activeRequest will always be the last reqId sent out 
    activeRequest = reqId; 

    $http.get('/api/something', {data: params}) 
     .then(function(res){ 
      if(activeRequest == reqId){ 
       // this is the response for last request 
      } 
      else { 
       // response from previous request (typically gets ignored) 
      } 
     }); 
} 
0

您已經接受了答案,但我想與您分享一些代碼。

myapp.factory('formService', ['$http', '$filter', '$q', '$timeout', function ($http, $filter, $q, $timeout) { 
    var service = {}; 
    service.delayPromise = null; 
    service.canceler = null; 
    service.processForm = function (url, formData, delay) { 
     if (service.delayPromise) 
      $timeout.cancel(service.delayPromise); 
     if (service.canceler) 
      service.canceler.resolve(); 
     service.canceler = $q.defer(); 
     service.delayPromise = $timeout(function (service) { 
      return service; 
     }, delay, true, service); 
     return service.delayPromise.then(function (service) { 
      service.delayPromise = null; 
      return $http({ 
       method : 'POST', 
       url  : url, 
       timeout : service.canceler.promise, 
       data : formData 
      }); 
     }) 
    } 
    return service; 
]); 

這是做什麼的。它提供了formService具有processForm函數,接受url,formDatadelay

processForm功能延遲提交$timeout服務。如果已經存在延遲或正在提交,它只是取消它。

並在你的控制器。

myapp.controller('myCtrl', ['formService', function (formService) { 
    $scope.formData = {}; 
    $scope.pageData = {}; 
    $scope.$watchCollection('formData', function (formData, oldData, scope) { 
     if (!angular.equals(formData, oldData)) { 
     var event; 
     formService.processForm(formData, event, 500).then(function (response) { 
      if (response.data instanceof Object) 
      angular.copy(response.data, scope.pageData); 
     }); 
     } 
    }); 
}]);