Переход $state после отклоненного обещания Angular ui-router

Я использую Angular ui-router и настроил функцию разрешения для одного из моих состояний до инициализации контроллера. Я извлекаю некоторые данные, прохожу цикл и сопоставляю их с URL-адресом stateParam, и, если совпадение найдено, разрешаю обещание контроллеру и возвращаю этот объект в обещании. Это все работает хорошо.

Однако, если совпадение не найдено, я просто хочу перенаправить в другое состояние, отклонив обещание и запустив $state.go('state');

Просто это:

deferred.reject();
$state.go('state',{params: 'param'});

Но это, кажется, ничего не делает. Контроллер просто зависает, и я не получаю никаких ошибок консоли или чего-то еще. Есть идеи?

Этот вопрос относится к версии 0.xx, в версии 1.xx многое изменилось


person Sean Thompson    schedule 19.02.2014    source источник
comment
Можете ли вы предоставить больше кода? Это внутри цикла $digest?   -  person rtcherry    schedule 19.02.2014
comment
Извините, что теперь яснее ... это в моей конфигурации приложения для $stateProvider, оно находится в разрешении для одного из моих состояний.   -  person Sean Thompson    schedule 19.02.2014


Ответы (2)


Предполагается, что ui-router выдает $stateChangeError, если разрешение маршрута отклонено. Вам нужно следить за этим событием и инициировать там переход состояния.

Согласно вики:

$stateChangeError — срабатывает при возникновении ошибки при переходе. Важно отметить, что если у вас есть какие-либо ошибки в ваших функциях разрешения (ошибки javascript, несуществующие службы и т. д.), они не будут выдаваться традиционно. Вы должны прослушивать это событие $stateChangeError, чтобы поймать ВСЕ ошибки.

https://github.com/angular-ui/ui-router/wiki#wiki-state-change-events


Как упомянул @gustavohenke в комментариях, хорошим местом для размещения этого обработчика является основная функция .run() вашего приложения.

person Matt Way    schedule 19.02.2014
comment
Спасибо. Не думал об этом. - person Sean Thompson; 19.02.2014
comment
Я сам пробовал прослушивать событие $stateChangeError и никогда не видел, чтобы оно срабатывало, даже когда я знаю, что был вызван $q.reject. Это оставляет приложение в предыдущем состоянии без уведомлений или, в случае первой загрузки, в неизвестном состоянии. - person weierophinney; 02.04.2014
comment
Вам нужно убедиться, что вы обрабатываете $stateChangeError в контроллере, который был загружен (например, выше в иерархии, чем ваш вызов разрешения). Если вам нужно поймать корневое состояние, используйте ng-controller в теге html или body в качестве всегда загружаемого контроллера для всего сайта. - person Matt Way; 15.04.2014
comment
@MattWay еще лучше: используйте блок запуска и слушайте в $rootScope. - person gustavohenke; 10.12.2014
comment
ui-router.github.io/guide/ ng1/ $stateChangeError устарел, используйте перехватчики перехода - person Simon D; 01.12.2017

Вы неправильно понимаете, как работают обещания. deferred.reject() просто уведомляет deferred.promise об отклонении.

var promise = deferred.promise;

promise.then(
  function (result) { 
    // this function runs if the promise was resolved
  },
  function (result) {
    // this function runs if the promise was rejected
    // this is where you should put $state.go(..)
  }
)
person Gabe    schedule 19.02.2014
comment
Он спрашивает о том, как обрабатывать отказ при разрешении, он точно знает, что такое обещание отвергнуть! - person cheziHoyzer; 11.05.2016