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

IT技术 javascript angularjs tabs angular-ui-router
2021-02-04 10:09:56

我正在创建一个基于选项卡的页面,该页面显示一些数据。我在 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 演示

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

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

6个回答

更新: 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 的评论中添加选项以保留浏览器历史记录。

@Swordfish0321 修复后退按钮,进行这个小改动:$state.go(to.redirectTo, params, {location: 'replace'});这将导致新状态替换历史记录中的先前状态(即我们被重定向的状态)。请参阅 $state.go 的文档:angular-ui.github.io/ui-router/site/ #/ api/...
2021-03-15 10:09:56
ui-router 1.0 内置了对此的支持:ui-router.github.io/guide/ng1/...
2021-03-24 10:09:56
只是想补充一点,这与我想要做的非常接近,但我想要默认 URL 而不是替换它,这很容易通过更改'$stateChangeStart''$stateChangeSuccess'
2021-03-27 10:09:56
这似乎破坏了后退按钮。
2021-04-02 10:09:56

事实上,即使Radim提出的这个解决方案完全可以胜任,我也需要记住每个选项卡的子选项卡(状态)。

所以我找到了另一个解决方案,它做同样的事情,但也记住每个选项卡子状态。

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

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

谢谢!

ui-router 的1.0 版开始,它支持一个redirectTo属性。例如:

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

由于版本1.0 UI-路由器,默认钩已经使用引入IHookRegistry.onBefore()所证明的示例数据驱动默认子状态http://angular-ui.github.io/ui-router/feature-1.0/接口/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);
});
这种工作对我来说,虽然,我不得不调整它(也使用 ES6) $transitions.onBefore({ to: state => state.defaultSubstate != null }, trans => trans.router.stateService.target(trans.to().defaultSubstate));
2021-03-25 10:09:56
app.config(function($stateProvider,$urlRouterProvider){

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

    })
这个解决方案是最简单的,对我来说效果很好。
2021-03-24 10:09:56
您能否解释一下它的作用以及为什么它比现有答案更好?
2021-04-09 10:09:56
这是迄今为止最好的答案。比使用更改事件更简洁。无需添加包。我不知道这对任何人来说都不清楚。我不知道接受的答案是如何获得如此高的投票的。
2021-04-11 10:09:56