2016-02-13 13 views
18

Jak można anulować bieżące żądanie kątowe $ http, gdy pojawi się nowe żądanie?

Mam aplikację Angular z widokiem, że aktualizacje są wyświetlane w trybie użytkownika. Czasami stare żądania są uzupełniane po ostatnim żądaniu, co oznacza, że ​​widok wyświetla nieprawidłowe dane. Jaki jest najprostszy sposób na anulowanie poprzedniego żądania, gdy pojawi się nowy?

Korzystanie z Angular 1.5, o ile warto.

<input ng-model = "query" ng-keyup = "search()"/> 
{{results | json}} 

// In the controller: 
    $scope.search = function(){ 
     $http({ 
      method: "GET", 
      url: "/endpoint.php" 
      params: { 
       query: $scope.query 
      } 
     }).then(function(response){ 
      $scope.results = response.data; 
     }) 
    } 

Jedno rozwiązanie próbowałem:

// In the controller: 
    var canceler = $q.resolve(); // New 
    $scope.search = function(){ 
     canceler.resolve("Canceling old request");  // New 
     $http({ 
      method: "GET", 
      url: "/endpoint.php" 
      params: { 
       query: $scope.query 
      }, 
      timeout: canceler.promise // New 
     }).then(function(response){ 
      $scope.results = response.data; 
     }) 
    } 

W tym scenariuszu, chociaż ja dzwonię canceler.resolve zanim wniosek $ http, wniosek pojawia się jako "failed".

Jakieś spostrzeżenia?

edytuj: Rozwiązanie zostało znalezione!

// In the controller: 
    var canceler = $q.defer(); 

    $scope.search = function(){ 
     canceler.resolve("cancelled"); // Resolve the previous canceler 
     canceler = $q.defer();  // Important: Create a new canceler! 
             // Otherwise all $http requests made will fail 
     $http({ 
      method: "GET", 
      url: "/endpoint.php" 
      params: { 
       query: $scope.query 
      } 
     }).then(function(response){ 
      $scope.results = response.data; 
     }) 
    } 

Odpowiedz

5

Rozwiązaniem jest ustawienie obietnicy, a następnie przy każdym wyszukiwaniu() anuluj ją i ponownie zainicjuj nową. To będzie niezawodnie anulować poprzedni $ http():

var canceler = $q.defer(); 

$scope.search = function() { 

    canceler.resolve(); 

    canceler = $q.defer(); 

    $http({ 
     method: "GET", 
     url: "/endpoint.php" 
     params: { 
      query: $scope.query 
     } 
     timeout: canceler.promise 
    }).then(function(response) { 
     $scope.results = response.data; 
    }) 
} 
11

Kiedy rozpocząć nowe wyszukiwanie, wywołać funkcję cancel(). Możesz też użyć zmiennej resolved, aby się upewnić, że nie przerwiesz połączenia $http przed jego uruchomieniem. Coś takiego:

var canceler = $q.defer(); 
var resolved = false; 

var cancel = function() { 
    canceler.resolve("http call aborted"); 
}; 

$scope.search = function() { 
    if (resolved) { 
     cancel(); 
    } 

    canceler = $q.defer(); 
    resolved = true; 

    $http({ 
     method: "GET", 
     url: "/endpoint.php" 
     params: { 
      query: $scope.query 
     } 
     timeout: canceler.promise 
    }).then(function(response) { 
     $scope.results = response.data; 
     resolved = false; 
    }) 
} 

Nie zapomnij wstrzyknąć $q w kontrolerze/dyrektywa/usługi.

+0

Hmm - Staram this- 'ng-click = "cancel(); search();"' a ja wciąż to samo XHR zawiodły w mojej konsoli . Wstrzyknęłam też $ q. – schnauss

+0

@schnauss używasz anulatora var = $ q.resolve() lub var canceler = $ q.defer() ;? – NMSL

+0

'var canceler = $ q.defer();'. Jestem zdumiony. – schnauss

Powiązane problemy