使用UI-Router转换到父状态时将用户定向到子状态

Mee*_*ker 76 javascript angularjs angular-ui angular-ui-router

考虑以下:

.state('manager.staffList', {url:'^/staff?alpha', templateUrl: 'views/staff.list.html', data:{activeMenu: 'staff'}, controller: 'staffListCtrl'})
.state('manager.staffDetail', {url:'^/staff/{id}' , templateUrl: 'views/staff.html', data:{activeMenu: 'staff'}, controller: 'staffDetailsCtrl'})
  .state('manager.staffDetail.view', {url:'/view',  templateUrl: 'views/staff.details.html', data:{activeMenu: 'staff'}})
    .state('manager.staffDetail.view.schedule', {url:'/schedule', templateUrl:'views/staff.view.schedule.html', data:{activeMenu: 'staff'}})
    .state('manager.staffDetail.view.history', {url:'/history' , templateUrl:'views/staff.view.history.html', data:{activeMenu: 'staff'}})
    .state('manager.staffDetail.view.log', {url:'/log', templateUrl:'views/staff.view.log.html', data:{activeMenu: 'staff'}})
    .state('manager.staffDetail.view.files', {url:'/files', templateUrl:'views/staff.view.files.html', data:{activeMenu: 'staff'}})
  .state('manager.staffDetail.edit', {url:'/edit',  templateUrl: 'views/staff.edit.html', data:{activeMenu: 'staff'}})
Run Code Online (Sandbox Code Playgroud)

如果我去domain.com/staff/1234/view,我如何默认为manager.staffDetail.view.schedule子状态?

Tim*_*erg 136

  1. 首先,将属性添加到'manager.staffDetail.view'状态abstract:true.这不是必需的,但你想设置它,因为你永远不会直接进入这个状态,你总是会去其中一个子状态.

  2. 然后执行以下操作之一:

    • 'manager.staffDetail.view.schedule'状态提供一个空URL.这将使其与父状态URL匹配相同的URL,因为它不会向父URL添加任何内容.

      .state('manager.staffDetail.view.schedule', {url:'', ...

    • 或者,如果要保持默认子路由的URL不变,请在module.config中设置重定向.此处的代码将重定向'/staff/{id}/view'到以下位置的任何位置'/staff/{id}/view/schedule':

      $urlRouterProvider.when('/staff/{id}/view', '/staff/{id}/view/schedule');

  • 对于`$ urlRouterProvider`重定向,当使用带有'ui-sref ="manager.staffDetail.view"的链接时出现错误,所以我需要从父状态声明中删除`abstract:true`. (4认同)
  • 第二个选项不适用于内部ui-sref链接(它不会转到子状态) (4认同)

rab*_*rab 20

要设置默认子视图,请选中此示例.点击Route 1加载默认状态route1.list

// For any unmatched url, send to /route1
$stateProvider
  .state('route1', {
      url: "/route1",
      abstract:true ,
      templateUrl: "route1.html"
  })
  .state('route1.list', {
      url: '',
      templateUrl: "route1.list.html",
      controller: function($scope){
        $scope.items = ["A", "List", "Of", "Items"];
      }
  })
  .state('route1.desc', {
      url: "/desc",
      templateUrl: "route1.desc.html",
      controller: function($scope){
        $scope.items = [];
      }
  })
  .state('route2', {
    url: "/route2",
    templateUrl: "route2.html"
  })
  .state('route2.list', {
    url: "/list",
    templateUrl: "route2.list.html",
    controller: function($scope){
      $scope.things = ["A", "Set", "Of", "Things"];
    }
  })
Run Code Online (Sandbox Code Playgroud)

  • 如果我们想在ui-sref中使用父状态,那么这有一个很大的问题 (2认同)

Chu*_*k D 8

我遇到了同样的问题,发现这个解决方案有效:

https://github.com/angular-ui/ui-router/issues/948#issuecomment-75342784

这是引自@christopherthielen的github

"现在,不要宣布你的州摘要,并使用这个食谱:"

 app.run($rootScope, $state) {
    $rootScope.$on('$stateChangeStart', function(evt, to, params) {
      if (to.redirectTo) {
        evt.preventDefault();
        $state.go(to.redirectTo, params)
      }
    });
  }

  $stateProvider.state('parent' , {
      url: "/parent",
      templateUrl: "parent.html",
      redirectTo: 'parent.child'
  });

  $stateProvider.state('parent.child' , {
      url: "/child",
      templateUrl: "child.html"
  });
Run Code Online (Sandbox Code Playgroud)

以下是该过程如何工作的细分:

  1. 用户导航到"父母"状态
  2. "$ stateChangeStart"事件被触发
  3. "$ stateChangeStart"的监听器捕获事件并将"toState"(即"parent")和"event"传递给处理函数
  4. 处理程序功能检查"toState"上是否设置了"redirectTo".
  5. 如果未设置"redirectTo",则不会发生任何事情,并且用户继续进入"toState"状态.
  6. 如果设置了"redirectTo",则事件被取消(event.preventDefault),$ state.go(toState.redirectTo)将它们发送到"redirectTo"(即"parent.child")中指定的状态.
  7. "$ stateChangeStart"事件再次被触发,但这次"toState"=="parent.child"并且未设置"redirectTo"选项,因此它继续"toState".


nvc*_*nvn 7

很晚,但我认为你可以"重定向"到你想要的状态.

.state('manager.staffDetail.view', {
    url:'/view',
    templateUrl: 'views/staff.details.html',
    controller: 'YourController'
})

app.controller('YourController', ['$state',
function($state) {
    $state.go('manager.staffDetail.view.schedule');
}]);
Run Code Online (Sandbox Code Playgroud)

您可以在州配置中直接写控制器.

  • 我试过了,但它会加载控制器,解析和任何onStateChange.我只是使用$ urlRouterProvider.when('/ app/service','/ app/service/list')来加强 (3认同)