【问题标题】:UI-Router doesn't get previous state on $stateChangeSuccessUI-Router 在 $stateChangeSuccess 上没有获得先前的状态
【发布时间】:2016-08-17 18:24:49
【问题描述】:

如果用户尚未完成所有必需的注册步骤,我需要阻止他们进入应用上的某些状态(仪表板和帐户)。如果用户尝试通过直接 URL 输入访问这些状态,我会将它们重定向回它们所在的位置。我正在对我的run 块做这个简单的检查,以有条件地重定向用户:

$rootScope.$on("$stateChangeSuccess", (event, toState, toParams, fromState, fromParams) => { 
    let shouldPreventNavigationToAccountPages = fromState.name.includes('enroll') && toState.parent === 'layout';

    if (shouldPreventNavigationToAccountPages) {
      redirectUser();
    }
} 

因此,如果用户来自“注册”状态(例如“enroll.step-one”)并尝试访问他们不允许访问的“布局”状态,则应重定向他们。但是,当我直接输入 URL 时(不点击链接),“fromState”返回以下对象:

{name: "", url: "^", views: null, abstract: true}

我无权访问之前的状态,也无法对fromState.name.includes('enroll') 执行检查。这是 UI-Router 中的默认行为吗?如果用户尝试通过直接在浏览器上输入 URL 来访问页面,有没有办法获得以前的状态?

【问题讨论】:

  • 你能用let shouldPreventNavigationToAccountPages = (!fromState.name || fromState.name.includes('enroll')) && toState.parent === 'layout';吗?
  • 如果用户通过在浏览器中输入 URL 访问状态,则应用正在从头开始加载,没有以前的状态。
  • @plong0:这行不通,因为用户可能会尝试从“布局”状态导航到另一个“布局”状态(例如,“/dashboard”到“/account-settings” ) 通过输入 URL 和您建议的逻辑不允许它。
  • 我认为您可能需要重新考虑如何检测他们是否已注册,而不是基于 fromState。

标签: angularjs angular-ui-router


【解决方案1】:

你很亲密。你所缺少的只是:

$rootScope.$on("$stateChangeSuccess", (event, toState, toParams, fromState, fromParams) => { 
    let shouldPreventNavigationToAccountPages = fromState.name.includes('enroll') && toState.parent === 'layout';
    if (shouldPreventNavigationToAccountPages) {
      //This
      event.preventDefault();
      redirectUser();
    }
} 

【讨论】:

    【解决方案2】:

    如果用户尚未完成所有必需的注册步骤,我需要阻止他们进入应用上的某些状态(仪表板和帐户)。

    通过拒绝解析器来防止用户进入某个状态。

    myApp.config(function($stateProvider, $urlRouterProvider) {
    
      $stateProvider
        .state('dashboard', {
          url: "/dashboard",
          resolve: { 
              enrolled: function(enrollmentStatus) {
                  if (enrollmentStatus.enrolled) {
                      return "enrolled";
                  } else {
                      //throw to reject resolve
                      throw "not enrolled";
                  };
              }
          },
          templateUrl: "partials/dashboard.html"
        })
    

    通过使用服务跟踪注册状态,可以拒绝状态更改而不考虑之前的状态。


    更新

    $stateChangeError 事件可用于处理拒绝。

    $rootScope.$on("$stateChangeError", function(event, toState, toParams, fromState, fromParams, error) {
      if (error && fromState.name=='') {
        $state.go("enroll");
      }
    });
    

    欲了解更多信息,请参阅UI Router $state API Reference -- $stateChangeError

    【讨论】:

    • 如果用户未注册,用户将无法知道发生了什么问题(空白页)。您可以执行$state.go('error'),然后在您的else 语句中返回$q.reject()
    • @MuliYulzary 查看有关使用 $stateChangeError 事件的更新
    • 我找到了一个不同的解决方案(不同的检查),它特定于我正在开发的应用程序(不是我可以在此处发布的通用解决方案),但我仍然会尝试实现它一段时间。非常感谢。
    猜你喜欢
    • 2013-05-14
    • 1970-01-01
    • 2015-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-11
    相关资源
    最近更新 更多