Обработка нескольких вызовов Ajax в функции поиска в угловых JS

0

Я применил функцию пользовательского поиска для моего углового приложения js.

Для этого я вызвал запрос Ajax для извлечения данных. Этот вызов происходит в событии изменения, и поэтому он несколько раз вызывает мой Ajax.

Пожалуйста, предлагайте, поскольку я новичок в угловых js.

  • 0
    и точная проблема, с которой вы столкнулись ...? Не могли бы вы поделиться кодом?
  • 0
    Моя проблема: скажем, я пишу что-то, а затем быстро стираю, а затем в бэк-энде уже произошли вызовы ajax, которые принесут какой-то результат после успеха.
Теги:

4 ответа

2
Лучший ответ

Вы можете использовать задержку (время простоя). Например, я набираю текстовое поле поиска. Если я простаиваю в течение 200 мс, 400 мс или в любое другое время, вы можете вызвать запрос AJAX.

Если я напечатаю salman, он назовет api 6 раз. но предположим, что у нас будет свободное время. мы будем вызывать, когда пользователь простаивает в течение определенного времени.

Чтобы реализовать его в угловом, вы можете использовать. $ 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()" />

Редактировать:

Если вы хотите пойти "чистым" угловым способом, вы сделаете это так:

//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
    вот как я делаю debouncing для моего поиска :) по какой причине вы используете setTimeout вместо $timeout сервиса angular?
  • 0
    Я просто пытался сделать это простым, не добавляя $ timeout 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, с formData 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);
        });
      }
    });
}]);

Ещё вопросы

Сообщество Overcoder
Наверх
Меню