2013-06-16 18 views
27

Przepraszam za moje dane co 2 sekundy, aby zachować je na bieżąco. Mój problem polega na tym, że gdy odwiedzam kolejną stronę, limit czasu pozostaje aktywny. Jak mogę anulować swój limit czasu po odwiedzeniu nowej strony?

function IndexCtrl($scope, $timeout, RestData) { 
    $scope.rd = {}; 

    (function getRestDataFromServer() { 
     RestData.query(function(data){ 
      $scope.rd = data; 
      $timeout(getRestDataFromServer, 2000); 
     }); 
    })(); 
} 

// EDIT znalazłem rozwiązanie, ale nie jestem pewien, czy to dobry. Kiedy zapisuję mój limit czasu do $ rootScope, mogę go anulować we wszystkich innych kontrolerach.

function IndexCtrl($scope, $rootScope, $timeout, RestData) { 
    $scope.rd = {}; 

    (function getRestDataFromServer() { 
     RestData.query(function(data){ 
      $scope.rd = data; 
      $rootScope.prom = $timeout(getRestDataFromServer, 2000); 
     }); 
    })(); 
} 

function newPageCtrl($scope, $rootScope, $timeout) { 
    $timeout.cancel($rootScope.prom); 
} 
+0

wypróbowałeś '$ timeout.cancel()'? – Cherniv

Odpowiedz

64

Istnieje kilka zdarzeń kątowych, które są emitowane podczas zmiany trasy. Można słuchać na nich w IndexCtrl użyciu $scope.$on i działać odpowiednio:

$ zniszczyć wydarzenie

var promise = $timeout(getRestDataFromServer, 2000); 
... 

$scope.$on('$destroy', function(){ 
    $timeout.cancel(promise); 
}); 

$ locationChangeStart

var promise = $timeout(getRestDataFromServer, 2000); 
... 

$scope.$on('$locationChangeStart', function(){ 
    $timeout.cancel(promise); 
}); 

$timeout() zwraca obiekt obietnicy. Ten obiekt może zostać dostarczony do funkcji $timeout.cancel(), aby anulować limit czasu.

+0

Dzięki! Właśnie tego szukałem. =) – fraherm

+0

W rzeczywistości jest to $ timeout.cancel (obietnica). –

+0

To prawda. Dziękuję za uwagę. Odpowiedź zaktualizowana. – Stewie

15

Odpowiedź Stewiego jest idealna. Chciałem podzielić się tą prostą funkcję pomocnika, który używam zamiast korzystania $timeout bezpośrednio, tak, że nigdy nie trzeba myśleć o tym problemie ponownie:

function setTimeout(scope, fn, delay) { 
    var promise = $timeout(fn, delay); 
    var deregister = scope.$on('$destroy', function() { 
     $timeout.cancel(promise); 
    }); 
    promise.then(deregister, deregister); 
} 

Dodałem tę funkcję do usługi zwanej miscUtils, i wstrzyknąć tę usługę zamiast wstrzykiwania $timeout. Następnie, na przykład, aby funkcję "Update", który kursuje co 30 sekund, aż $scope jest zniszczona:

update(); 
function update() { 
    // do the actual updating here 
    miscUtils.setTimeout($scope, update, 30000); 
} 

Edit dla tych mylić co się dzieje z deregister:

ten funkcja rejestruje detektor zdarzenia $destroy, ale po upływie limitu czasu nie jest już potrzebny; nie ma już czasu na anulowanie. scope.$on zwraca funkcję, która po wywołaniu wyrejestrowuje tego słuchacza. Tak więc promise.then(deregister) czyści ten nieuchronnie potrzebny słuchacz, gdy tylko skończy się limit czasu.

+0

To brzmi jak bardzo dobre rozwiązanie. Czy możesz udostępnić cały kod, na przykład przykład pracy, inkingując definicję usługi, więc dla mnie jako początkującego łatwiej jest zintegrować go z moją własną aplikacją? Dziękuję Ci! – SHernandez

+0

Zmienna 'deregister' wprawiła mnie w zakłopotanie przez chwilę, myślałem, że jest to funkcja anulowania limitu czasu, ale tak nie jest. Jest to funkcja anulowania anulowania limitu czasu. – dshepherd

+0

@dshepherd proszę wyjaśnić, ponieważ nadal jestem zdezorientowany. – natanavra