developer tip

UI-Router를 사용하여 상위 상태로 전환 할 때 사용자를 하위 상태로 안내

optionbox 2020. 10. 16. 07:20
반응형

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

로 이동하면 domain.com/staff/1234/view어떻게 manager.staffDetail.view.schedule자식 상태로 기본 설정 됩니까?


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


기본 자식보기를 설정하려면이 예제를 확인하십시오 . 클릭 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"];
    }
  })

동일한 문제가 발생하여이 솔루션이 작동하는 것으로 나타났습니다.

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

이것은 github의 @christopherthielen에서 인용했습니다.

"지금은 상태 요약을 선언하지 말고 다음 레시피를 사용하세요."

 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"
  });

다음은 프로세스 작동 방식에 대한 분석입니다.

  1. 사용자가 "부모"상태로 이동
  2. "$ stateChangeStart"이벤트가 시작됩니다.
  3. Listener for “$stateChangeStart” catches event and passes “toState” (which is “parent”) and “event" to the handler function
  4. Handler function checks if “redirectTo” is set on “toState”.
  5. If “redirectTo” IS NOT set, nothing happening and the user continues on to the “toState” state.
  6. If “redirectTo" IS set, the event is canceled (event.preventDefault) and $state.go(toState.redirectTo) sends them to the state specified in “redirectTo” (which is “parent.child”).
  7. The “$stateChangeStart” event gets fired again, but this time “toState” == “parent.child” and the “redirectTo” option is not set, so it continues to “toState”.

Quite late but I think you can "redirect" to the state you want.

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

You can write you controller right in the state config for short.


I changed 'manager.staffDetial.view' to an abstract state and left the url of my default child state to blank ''

// Staff
.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', abstract: true, templateUrl: 'views/staff.details.html', data:{activeMenu: 'staff'}})
    .state('manager.staffDetail.view.schedule', {url:'', 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'}})

In "angular-ui-router": "0.2.13", I don't think @nfiniteloop's redirect solution will work. It worked once I had rolled back to to 0.2.12 (and may have had to put the $urlRouterProvider.when call before the $stateProvider?)

see https://stackoverflow.com/a/26285671/1098564

and https://stackoverflow.com/a/27131114/1098564 for a workaround (if you don't want to go back to 0.2.12)

as of Nov 28 2014, https://github.com/angular-ui/ui-router/issues/1584 indicates that it should work again in 0.2.14


This is late but all the answers here don't apply to the latest version of angular-ui-router for AngularJS. As of that version (specifically @uirouter/angularjs#v1.0.x you can just put redirectTo: 'childStateName' in the second param of $stateProvider.state(). For example:

$stateProvider
.state('parent', {
  resolve: {...},
  redirectTo: 'parent.defaultChild'
})
.state('parent.defaultChild', {...})

Here is the relevant doc section: https://ui-router.github.io/guide/ng1/migrate-to-1_0#state-hook-redirectto

Hopefully this helps someone!


here is a very simple and transparent alternative by just modifying parent state in ui router:

  .state('parent_state', {
    url: '/something/:param1/:param2',
    templateUrl: 'partials/something/parent_view.html',  // <- important
    controller: function($state, $stateParams){
      var params = angular.copy($state.params);
      if (params['param3'] === undefined) {
        params['param3'] = 'default_param3';
      }
      $state.go('parent_state.child', params) 
    }
  })

  .state('parent_state.child', {
    url: '/something/:param1/:param2/:param3',
    templateUrl: '....',  
    controller: '....'
  })

Add angular-ui-router-default and add the abstract and default options to the parent state:

...

.state('manager.staffDetail.view', {abstract: true, default: '.schedule', 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'}})

...

Note: for this to work, the parent template must have <ui-view/> somewhere in it.

참고URL : https://stackoverflow.com/questions/17001589/directing-the-user-to-a-child-state-when-they-are-transitioning-to-its-parent-st

반응형