使用AngularJS中的UI-Router将状态重定向到默认子状态


89

我正在创建一个基于标签的页面,其中显示了一些数据。我在AngularJs中使用UI-Router来注册状态。

我的目标是在页面加载时打开一个默认选项卡。每个选项卡都有子选项卡,我想在更改选项卡时打开默认的子选项卡。

我正在使用onEnter函数进行测试,并且正在使用内部,$state.go('mainstate.substate');但是由于循环效应问题(在state.go上对其子状态调用它的父状态,依此类推,然后变成循环),它似乎无法正常工作。

$stateProvider

.state('main', {
  url: '/main',
  templateUrl: 'main.html',
  onEnter: function($state) {
    $state.go('main.street');
  }
})

.state('main.street', {
  url: '/street',
  templateUrl: 'submenu.html',
  params: {tabName: 'street'}
})

在这里,我创建了一个plunker演示

目前,一切正常,除了我没有打开默认选项卡,而这正是我所需要的。

感谢您的建议,意见和想法。

Answers:


172

更新: 1.0向前支持开箱即用的redirectTo。

https://ui-router.github.io/ng1/docs/latest/interfaces/state.statedeclaration.html#redirectto


我在这里创建了一个示例

该解决方案来自一个不错的“注释”,它涉及到使用.when() https://stackoverflow.com/a/27131114/1679310进行重定向的问题,并且一个非常不错的解决方案(由Chris T,但原始帖子由yahyaKacem撰写)

https://github.com/angular-ui/ui-router/issues/1584#issuecomment-75137373

因此,首先让我们通过重定向设置扩展main:

$stateProvider
    .state('main', {
      url: '/main',
      templateUrl: 'main.html',
      redirectTo: 'main.street',
    })

并只添加这几行

app.run(['$rootScope', '$state', function($rootScope, $state) {

    $rootScope.$on('$stateChangeStart', function(evt, to, params) {
      if (to.redirectTo) {
        evt.preventDefault();
        $state.go(to.redirectTo, params, {location: 'replace'})
      }
    });
}]);

这样我们就可以使用默认重定向来调整我们的任何状态... 在此处检查

编辑:@Alec从注释中添加了选项,以保留浏览器历史记录。


4
这似乎使后退按钮变得混乱。
Scott Sword

6
@ Swordfish0321修复后退按钮,请进行以下较小更改:$state.go(to.redirectTo, params, {location: 'replace'});这将导致新状态替换历史记录中的前一个状态(即,我们正在从中重定向的状态)。参见$ state.go的文档:angular-ui.github.io/ui-router/site
Alec

2
只是想补充一点,这确实很接近我想做的事情,但是我想要默认的URL而不是替换它,这很容易通过更改'$stateChangeStart''$stateChangeSuccess'
Matti Price

6
UI路由器1.0已经内置支持此:ui-router.github.io/guide/ng1/...
格特-扬

21

实际上,即使Radim提出的这种解决方案确实可以完成工作,我也需要记住每个选项卡的子选项卡(状态)。

因此,我发现了另一个解决方案,该解决方案可以执行相同的操作,但还可以记住每个选项卡的子状态。

我要做的就是安装ui-router-extras并使用深度状态重定向功能:

$stateProvider
  .state('main.street', {
     url: '/main/street',
     templateUrl: 'main.html',
     deepStateRedirect: { default: { state: 'main.street.cloud' } },
  });

谢谢!



7

自ui路由器1.0版以来,已使用IHookRegistry.onBefore()引入了默认钩子,如http://angular-ui.github.io/ui-router/feature-1.0/中的数据驱动默认子状态示例所示。interfaces / transition.ihookregistry.html#onbefore

// state declaration
{
  name: 'home',
  template: '<div ui-view/>',
  defaultSubstate: 'home.dashboard'
}

var criteria = {
  to: function(state) {
    return state.defaultSubstate != null;
  }
}
$transitions.onBefore(criteria, function($transition$, $state) {
  return $state.target($transition$.to().defaultSubstate);
});

不过,对我来说,这种工作$transitions.onBefore({ to: state => state.defaultSubstate != null }, trans => trans.router.stateService.target(trans.to().defaultSubstate));
非常困难

3
app.config(function($stateProvider,$urlRouterProvider){

    $urlRouterProvider.when("/state","/state/sub-state");

    })

1
您能否提供有关此功能的解释以及为什么它比已有的答案更好?
Equalsk

此解决方案最简单,对我来说效果很好。
BuffMcBigHuge

到目前为止,这是最好的答案。比使用更改事件更简洁。无需添加软件包。我不知道这对所有人来说还不清楚。我不知道被接受的答案是如何被如此强烈地评价的。
CodeWarrior

1

如果有人来这里寻求有关如何为状态实施简单重定向的答案,并且发生在我身上,那将没有机会使用新路由器...

显然,如果可以的话,@ bblackwo的答案也很棒:

$stateProvider.state('A', {
  redirectTo: 'B',
});

如果您不能手动重定向,请执行以下操作:

$stateProvider.state('A', {
  controller: $state => {
    $state.go('B');
  },
});

希望对您有所帮助!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.