使用 AngularJS 中的 UI-Router 将状态重定向到默认子状态
Posted
技术标签:
【中文标题】使用 AngularJS 中的 UI-Router 将状态重定向到默认子状态【英文标题】:Redirect a state to default substate with UI-Router in AngularJS 【发布时间】:2015-06-12 00:28:31 【问题描述】:我正在创建一个基于标签的页面,其中显示了一些数据。 我在 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 demo。
现在一切正常,只是我没有打开默认选项卡,而这正是我需要的。
感谢您的建议、意见和想法。
【问题讨论】:
【参考方案1】:更新: 1.0 以后支持 redirectTo 开箱即用。
https://ui-router.github.io/ng1/docs/latest/interfaces/state.statedeclaration.html#redirectto
我创建了an example here。
这个解决方案来自一个很好的“评论”到一个使用.when()
重定向的问题(https://***.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')
);
]);
这样我们可以使用默认重定向调整我们的任何状态...检查它here
编辑:从@Alec 的评论中添加了选项以保留浏览器历史记录。
【讨论】:
这似乎破坏了返回按钮。 @Swordfish0321 修复后退按钮,进行以下小改动:$state.go(to.redirectTo, params, location: 'replace');
这将导致新状态替换历史记录中的先前状态(即我们被重定向的状态)。查看 $state.go 的文档:angular-ui.github.io/ui-router/site/#/api/…
只是想补充一点,这与我想要做的非常接近,但我想要默认 URL 而不是替换它,这很容易通过将 '$stateChangeStart'
更改为 '$stateChangeSuccess'
来实现/跨度>
ui-router 1.0 内置了对此的支持:ui-router.github.io/guide/ng1/…【参考方案2】:
事实上,即使 Radim 提出的这个解决方案确实有效,我也需要记住每个标签的子标签(状态)。
所以我找到了另一个解决方案,它做同样的事情,但也记住每个选项卡子状态。
我所要做的就是安装ui-router-extras 并使用deep state redirect 功能:
$stateProvider
.state('main.street',
url: '/main/street',
templateUrl: 'main.html',
deepStateRedirect: default: state: 'main.street.cloud' ,
);
谢谢!
【讨论】:
【参考方案3】:从 ui-router 1.0 版开始,使用 IHookRegistry.onBefore() 引入了默认挂钩,如 http://angular-ui.github.io/ui-router/feature-1.0/interfaces/transition.ihookregistry.html#onbefore 中的示例 Data Driven Default Substate 所示
// 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);
);
【讨论】:
这种工作对我来说,虽然,我不得不调整它(也使用 ES6)$transitions.onBefore( to: state => state.defaultSubstate != null , trans => trans.router.stateService.target(trans.to().defaultSubstate));
【参考方案4】:
从 ui-router 的 version 1.0 开始,它支持 redirectTo
属性。例如:
.state('A',
redirectTo: 'A.B'
)
【讨论】:
【参考方案5】:app.config(function($stateProvider,$urlRouterProvider)
$urlRouterProvider.when("/state","/state/sub-state");
)
【讨论】:
您能否解释一下它的作用以及为什么它比现有答案更好? 这个解决方案是最简单的,对我来说效果很好。 这是迄今为止最好的答案。比使用更改事件更简洁。无需添加包。我不知道这对任何人来说都不清楚。我不知道接受的答案如何得到如此多的支持。【参考方案6】:如果有人来这里是为了回答有关如何为一个状态实现简单重定向的答案,并且就像我遇到的那样,没有机会使用新的路由器......
如果可以的话,很明显,@bblackwo 的回答很棒:
$stateProvider.state('A',
redirectTo: 'B',
);
如果你不能,那就手动重定向它:
$stateProvider.state('A',
controller: $state =>
$state.go('B');
,
);
希望对你有帮助!
【讨论】:
以上是关于使用 AngularJS 中的 UI-Router 将状态重定向到默认子状态的主要内容,如果未能解决你的问题,请参考以下文章
使用AngularJS中的UI-Router将状态重定向到默认子状态
angularjs 中的选项卡无法与 UI-Router 和 UI-bootstrap 一起正常工作
如何在 angularjs ui-router 中的状态之间共享 $scope 数据?