【问题标题】:UI Router: Keep url after $stateChangeError (while resolving dependencies)UI 路由器:在 $stateChangeError 之后保留 url(解决依赖关系时)
【发布时间】:2016-07-27 12:16:53
【问题描述】:

场景:

1) 我们处于状态 A
2) 用户点击链接(目标是状态 B)
3) $stateChangeStart
4) 状态 B 的依赖关系得到解决,抛出一个错误
5) $stateChangeError
6) url 仍然是状态 A

想要的行为:

  • 我想打开一个包含错误消息的模式对话框
  • Url 应该是状态 B 的 url(这样用户可以将链接发送给我们或点击刷新重试)
  • 理想情况下,状态 A 的视图仍在模态框的背景中
  • 返回浏览器历史记录应该让我们回到状态 A(模式可以侦听 popstate 事件并自行关闭)
  • 关闭模式也应该让我们回到状态 A(所以再次更改 url)

一般来说,要在不重新加载视图的情况下更改 url,我会执行以下操作:

// in .config() block
$urlRouterProvider.deferIntercept();

// somewhere else
var preventNextSuccess = false;
var unbindError = $rootScope.$on('$stateChangeError', function () {
     preventNextSuccess = true;
     $location.path($state.href(toState, toParams));
     unbindError();
});

$rootScope.$on('$locationChangeSuccess', function $event) {
    if (preventNextSuccess) {
         $event.preventDefault();
         preventNextSuccess = false;
    } else {
         $urlRouter.sync();
    }
});

$urlRouter.listen();

但在这种情况下,阻止 $locationChangeSuccess 事件并没有帮助,因为错误出现在 $locationStateStart 和 $stateChangeStart 之后以及 $locationChangeSuccess 和 $stateChangeSuccess 之前。

因此,通过此解决方案,我得到了一个无限循环。 阻止启动事件也无济于事,因为在这种情况下不会设置 url。

有没有人知道如何实现这一目标?在此先感谢:)

【问题讨论】:

    标签: javascript angularjs error-handling angular-ui-router


    【解决方案1】:

    我找到了一种适用于我们案例的方法:

    $rootScope.$on('$stateChangeError', function ($event, toState, toParams, fromState, fromParams, response) {
        ErrorModalService.openErrorModal({error: error});
        var failedStateUrl = $state.href(toState, toParams);
        var fromStateUrl = $state.href(fromState, fromParams);
    
        if (fromStateUrl !== null && fromStateUrl !== failedStateUrl) {
              var unbindLocationChange = $rootScope.$on('$locationChangeStart', function ($event) {
                   $event.preventDefault();
                   unbindLocationChange();
              });
              // After $stateChangeError, the url gets set back to the url of the previous state.
              // We want to keep the failedUrl (without reloading that state though)
              $timeout(function () {
                 history.pushState(null, '', failedStateUrl);
              });
       }
    });
    

    【讨论】:

      猜你喜欢
      • 2017-07-04
      • 1970-01-01
      • 1970-01-01
      • 2020-10-07
      • 2017-03-02
      • 1970-01-01
      • 2014-12-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多