2015-03-16 11 views
7

Używam routera UI w mojej aplikacji i używam detektora $stateChangeStart, aby pokazać program ładujący i $stateChangeSuccess, aby ukryć moduł ładujący. W ten sposób mam ładowarkę między przejściami stanów.Jak być informowanym o anulowaniu zmian stanu w ui-routerze?

$rootScope.$on('$stateChangeStart', 
       function (event, toState, toParams, fromState, fromParams) { 
///show loader 
}); 

$rootScope.$on('$stateChangeSuccess', 
       function (event, toState, toParams, fromState, fromParams) { 
//hide loader 
}); 

Problem:

  1. jestem w stanie
  2. kliknięciu na przycisk, aby przejść do stanu B, $stateChangeStart nazywa dla B, jest pokazana moja ładowarka.
  3. Natychmiast po kliknięciu na inny przycisk, aby przejść do kraju A (B ma kilka rzeczy do determinacji, więc nie ma czasu, zanim B UI faktycznie rozpoczyna ładowanie)
  4. B nie jest załadowany, a $stateChangeSuccess nie nazywa i mój loader nigdy nie jest ukryty (Ponieważ byliśmy już w A, nie jest ponownie załadowywany)

Czy istnieje sposób, w jaki mogę wysłuchać anulowania zmian stanu i ukryć mój moduł ładujący?

Aktualizacja: Utworzono Plunk. W spluwie dałem timeout 10 sekund w postanowieniu B. Zanim to rozwiąże, kliknij przycisk A. Monitoruj konsolę, aby wykryć zdarzenia zmiany stanu.

Aktualizacja 25 lipca 2015 r. Wykorzystująca najnowszy router AngularUI: Utworzono nowy Plunk.

+1

można łatwo osiągnąć poprzez utrzymywanie informacji o zmianach stanu wewnątrz usługi ... – harishr

+0

@entre Ale nie wiadomo, kiedy odwołanie wystąpił. –

+0

Czy coś jest nie tak z pierwszym wynikiem Google - https://github.com/angular-ui/ui-router/wiki#state-change-events? –

Odpowiedz

3

Jedynym trwałym rozwiązaniem, jakie udało mi się znaleźć, było uniknięcie użycia ui-sref. Maskuje on wartość zwracaną $state.go, która jest w tym przypadku kluczowa.

Sztuką jest, aby obsłużyć obietnicę transition zwrócony przez $state.go

$scope.safeGo = function(stateName){ 
    var transition = $state.go(stateName); 
    transition.then(function(currentState){ 
    console.log('Transition finished successfully. State is ' + currentState.name); 
    }) 
    .catch(function(err){ 
    //revert your loader animation here 
    console.log('Transition failed. State is ' + $state.current.name, err); 
    }) 
} 

tego samego obiektu można uzyskać za pośrednictwem $state.transition mienia jednak między przejściami nieruchomość jest null w którymś z wydarzeń, które $state transmisje jest również null. Tak więc jedyną solidną opcją jest pobranie wartości zwracanej $state.go.

Kiedy stan A wybrano przed B został rozwiązany transition obietnicę B odrzuci z powodu Error: transition superseded. Jednak nadal będziesz musiał poczekać, aż zostanie ukończone B.resolve. Jeśli chcesz tego uniknąć, będziesz musiał samodzielnie śledzić swoje stany, ponieważ przejście na A zostanie natychmiast rozwiązane (ponieważ bieżący stan to nadal A, podczas gdy B próbuje rozwiązać).

Updated plunker