2015-02-19 11 views
5

Jestem pojawia się następujący błąd z kątowym-UI-Router:

TypeError: Cannot read property '@' of null 
... 
TypeError: Cannot read property '@main' of null 
... 

Zrobiłem kilka badań na temat tego, co może być przyczyną ten błąd i doszli do wniosku, że problem polega na tym, że wykonuję przekierowanie, gdy warunek jest fałszywy przez $ state.go (stan) podczas wykonywania innego stanu.

Oto niektóre dyskusje dotyczące tego samego problemu na github:

Próbowałem niektóre z propozycji, ale nie działają. Wydaje się, że nie zapewniają rozwiązania, ale po prostu wskazują problem, a według dyskusji github this powinien on zostać rozwiązany, ale nie mogę sprawić, żeby działał.

Używam AngularJS v1.2.24 i ui-router v0.2.11.

za pomocą następującego kodu (uproszczony):

.state('main', { 
    abstract: true, 
    url: '/main', 
    templateUrl: '/main/_layout.html' 
}) 
.state('main.home', { 
    url: '/home', 
    templateUrl: '/main/home/home.html', 
    controller: 'HomeCtrl', 
    onEnter: function ($state) 
    { 
     if (condition === true){ 
      $state.go('main.catch') 
     } 
    } 
}) 
.state('main.catch', { 
    url: '/catch', 
    templateUrl: '/main/catch/catch.html', 
    controller: 'CatchCtrl' 
}) 

Czy istnieje sposób, aby uzyskać to do pracy? Czy powinienem rozważyć zupełnie inne podejście, aby osiągnąć ten sam rezultat?

P.S .: Możliwym rozwiązaniem jest wykonać następujące czynności w sterowniku,

$scope.$on('$stateChangeSuccess', function(){ 
    // conditional redirect here 
} 

Ale nie chcę, aby to zrobić w HomeCtrl.

+1

ty przekierowanie z 'main. catch' to 'main.catch'? – Sulthan

+0

oeps, to jest literówka. Przekierowuje on do main.catch z main.home => corrected –

+0

Czy nie pomogłoby, gdyby warunek został rozstrzygnięty zamiast onEnter? – tomastrajan

Odpowiedz

1

Mam napotkał podobną sytuację i rozwiązać to w ten sposób:

.state('main.home', { 
    url: '/home', 
    templateUrl: '/main/home/home.html', 
    controller: 'HomeCtrl', 
    onEnter: function ($state) 
    { 
     if (condition === true){ 
      $timeout(function() { 
       $state.go('main.catch') 
      )}; 
     } 
    } 
}) 

Sztuką jest to, że chcesz, aby oryginalne wykończenie zmiana stanu zamiast próbować przekierować w środku zmiany stanu. Limit czasu $ pozwala na zakończenie pierwotnej zmiany stanu, a następnie natychmiast uruchamia zmianę do pożądanego stanu.

+0

Zamiast używać $ timeout, polecam użycie właściwości '$ state.transition', jeśli jest tam (w przeciwnym razie,' $ timeout' nie jest potrzebny, i będzie uruchamiany bez polegania na tym, że zegar jest poprawny). na przykład spróbuj tego: 'function afterTransition ($ state, action) { if ($ state.przejście) { $ state.transition.finally (akcja); } else { else ( akcja(); } } ' –

0

dobrze, wiem, że to trochę późno, ale miewam ten problem przez długi czas, a ja w końcu rozwiązany przez słuchanie przypadku $viewContentLoading:

$rootScope.$on('$viewContentLoading', function(){ 
    if(!$state.$current.locals) 
     $state.$current.locals = {}; 
});