2016-07-30 2 views
0

私は角度jsアプリケーションのカスタム検索機能を実装しました。角度jsの検索機能で複数のAjax呼び出しを処理する

そのために、データを取得するAjaxリクエストを呼び出しました。 このコールはchangeイベントで発生し、それが私のAjaxを複数回呼び出す理由です。

私は角度jsで新しいとお勧めします。

+0

あなたが直面している正確な問題は...?いくつかのコードを共有してもよろしいですか? – CozyAzure

+0

私の問題は次のとおりです。何かを書いてすぐに消してしまえば、バックエンドですでに成功した後に結果が出るajaxコールが起こっています。 –

答えて

2

遅延(アイドル時間)を考慮することができます。たとえば、検索テキストボックスに入力していると仮定します。200ms、400ms、または任意の時間にアイドル状態であれば、AJAXリクエストを呼び出すことができます。

salmanと入力すると、apiが6回呼び出されます。私たちが遊んでいる時間があるとします。その特定の時間、ユーザーがアイドル状態のときに呼び出されます。

角度で実装するには、を使用できます。 $ウォッチまたはブートストラップの指示文

2

あなたの最善の策は、少し遅れを取ることです。 Akashが指摘しているように、あなたは許容可能な遅延時間を選択する必要があります。また、遅延が発生した後にのみ要求が行われるようにする必要があります。ここで

はそれを行うための一つの方法である:

//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()" /> 

を編集:

は、あなたが '純粋な' 角度の道を行くしたい場合は、このようにする:

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

これは、私が私の検索のためにデバウンする方法です:角度の '$ timeout'サービスの代わりに' setTimeout'を使用している理由は何ですか? – plong0

+0

私はちょうど$タイムアウトDIなどを追加せずに単純に保つためにしていた。しかし、ええ、私は私の答えを修正しました。ありがとう! –

1

私は間違いなく "debouncing"のための@ jeanpaulの答えをお勧めします。

さらに、複数の同時AJAX要求が発生する可能性があり、最新のものを処理したい場合は、応答ハンドラ内の要求を確認する必要があります。応答は常に彼らが要求されたのと同じ順序で来ていないとき、これは特に重要であるこれを解決する

道のようなものである(つまり、以前の要求は後で1以上の応答に時間がかかります。):

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を提供し、url,formDataおよびdelayを受け入れます。

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); 
     }); 
     } 
    }); 
}]); 
関連する問題