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

我正在创建一个基于选项卡的页面,其中显示了一些数据。 我在 AngularJs 中使用 UI 路由器来注册状态。

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

我用 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'}
})

在这里我创建了一个 普鲁克演示

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

谢谢你的建议,意见和想法。

90224 次浏览

Update: 1.0 Onwards Supports redirectTo out of the box.

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


I created an example here.

This solution comes from a nice "Comment" to an an issue with redirection using .when() (https://stackoverflow.com/a/27131114/1679310) and really cool solution for it (by Chris T, but the original post was by yahyaKacem)

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

So firstly let's extend main with redirection setting:

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

And add only this few lines into run

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'})
}
});
}]);

This way we can adjust any of our states with its default redirection...Check it here

EDIT: Added option from comment by @Alec to preserve the browser history.

In fact even if this solution proposed by Radim did exactly the job, I needed to remember every tab's sub tab (state).

So I found another solution which do the same thing but also remembers every tab substate.

I all have to do was to install ui-router-extras and use the deep state redirect feature:

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

Thank you!

Since version 1.0 of ui-router, a default hook has been introduced using IHookRegistry.onBefore() as demonstrated in the example Data Driven Default Substate in 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);
});

As of version 1.0 of the ui-router it supports a redirectTo property. For example:

.state('A', {
redirectTo: 'A.B'
})
app.config(function($stateProvider,$urlRouterProvider){


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


})

If someone comes here for an answer regarding how to implement a simple redirect for a state and, as it happened to me, doesn't have the opportunity to use the new router...

Obviously again if you can, @bblackwo answer is great:

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

If you can't then just manually redirect it:

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

I hope it helps!