У меня есть приложение AngularJS, которое использует ui-router и ui-router-extras, где одни переходы между состояниями перехватываются и перенаправляются в другие.
Таким образом, в основном, когда запускается событие $stateChangeStart
, приложение проверяет, разрешен ли этот переход или его нужно заблокировать, а затем перенаправляет пользователя куда-то еще (например, в диалоговое окно входа в систему, пропущенный шаг в процессе и т. д.). Переходы также можно отменить.
Перехват работает следующим образом:
$rootScope.$on("$stateChangeStart", function(e,to,toParams,from,fromParams){
if( <mustBeIntercepted> || <mustBeCancelled> ){
// this prevents the actual state change from happening
e.preventDefault();
if( <redirectionRequired> ){
$state.go( <stateName>, <stateParams>);
}
}
});
И это работает хорошо до сих пор. Проблема в том, что при отмене смены состояния $previousState
не знает об отмене, и прописывает текущее как предыдущее, так же как и если не отменять переход. Так что в основном $previousState
не знает об отмене перехода. Это приводит к тому, что при попытке программно вернуться в предыдущее состояние он не перемещается, потому что $state
== $previousState
.
Я создал живую демонстрацию здесь: http://plnkr.co/edit/dXjj2iSwDU1DtPMuqW1W?p=preview< /а>
По сути, вы нажимаете Шаг 1, а затем Подтвердить, приложение отменяет переход и предлагает подтвердить его. Если вы подтвердите, то он перейдет в первоначально желаемое состояние. Обратите внимание, что в реальном приложении это делается не с помощью confirm
, а с помощью пользовательского наложения, которое не может блокировать ответ так же, как это делает confirm
.
Как вы заметили, в верхней панели есть две метки, отображающие содержимое $state
и $previousState
. Если вы отмените подсказку confirm
, вы увидите, что $previousState
изменится на «Шаг 1», несмотря на то, что перехода не произошло.
Как я могу этого избежать?