Diriger l’utilisateur vers un état enfant lorsqu’il passe à son état parent à l’aide de UI-Router

Considérer ce qui suit:

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

Si je vais sur domain.com/staff/1234/view , comment puis-je utiliser par défaut l’état enfant manager.staffDetail.view.schedule ?

  1. Tout d’abord, ajoutez une propriété à l’état 'manager.staffDetail.view' du abstract:true . Ce n’est pas obligatoire, mais vous voulez définir cela car vous n’irez jamais directement dans cet état, vous irez toujours à l’un de ses états enfants.

  2. Effectuez ensuite l’ une des opérations suivantes:

    • Atsortingbuez à l’ 'manager.staffDetail.view.schedule' une URL vide . Cela le fera correspondre à la même url que l’url de l’état parent, car il n’ajoute rien à l’url parent.

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

    • Ou si vous souhaitez conserver l’URL de la route enfant par défaut inchangée, configurez une redirection dans votre module.config. Ce code ici va redirect n’importe quel emplacement de '/staff/{id}/view' vers l’emplacement de '/staff/{id}/view/schedule' :

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

Pour définir la vue enfant par défaut, consultez cet exemple . En cliquant sur Route 1 chargez l’état par défaut 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"]; } }) 

J’ai rencontré le même problème et j’ai trouvé cette solution efficace:

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

Ceci est cité de @christopherthielen sur github

“Pour l’instant, ne déclarez pas votre résumé d’état et utilisez cette recette:”

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

Voici comment se déroule le processus:

  1. L’utilisateur navigue pour indiquer «parent»
  2. L’événement «$ stateChangeStart» se déclenche
  3. L’auditeur de «$ stateChangeStart» intercepte l’événement et transmet «toState» (qui est «parent») et «event» à la fonction de gestionnaire
  4. La fonction Handler vérifie si «redirectTo» est défini sur «toState».
  5. Si “redirectTo” N’EST PAS défini, rien ne se produit et l’utilisateur continue vers l’état “toState”.
  6. Si «redirectTo» IS est défini, l’événement est annulé (event.preventDefault) et $ state.go (toState.redirectTo) les envoie à l’état spécifié dans «redirectTo» (qui est «parent.child»).
  7. L’événement «$ stateChangeStart» est à nouveau déclenché, mais cette fois «toState» == «parent.child» et l’option «redirectTo» n’est pas définie. Il continue donc à «afficher».

Assez tard mais je pense que vous pouvez “redirect” vers l’état que vous voulez.

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

Vous pouvez écrire votre contrôleur directement dans la configuration d’état pour faire court.

J’ai changé ‘manager.staffDetial.view’ en un état abstrait et j’ai laissé l’url de mon état enfant par défaut vide ”

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

Dans “angular-ui-router”: “0.2.13”, je ne pense pas que la solution de redirection de @ nfiniteloop fonctionnera. Cela a fonctionné une fois que j’ai été rétabli à 0.2.12 (et peut-être dû mettre le $ urlRouterProvider.when appel avant le $ stateProvider?)

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

et https://stackoverflow.com/a/27131114/1098564 pour une solution de contournement (si vous ne souhaitez pas revenir en 0.2.12)

au 28 novembre 2014, https://github.com/angular-ui/ui-router/issues/1584 indique qu’il devrait fonctionner à nouveau en 0.2.14

C’est tard, mais toutes les réponses ne s’appliquent pas à la dernière version du routeur angular pour AngularJS. A partir de cette version (en particulier @ uirouter / angularjs # v1.0.x, vous pouvez simplement placer redirectTo: 'childStateName' dans le second $stateProvider.state() de $stateProvider.state() . Par exemple:

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

Voici la section appropriée du document: https://ui-router.github.io/guide/ng1/migrate-to-1_0#state-hook-redirectto

J’espère que cela aide quelqu’un!

Voici une alternative très simple et transparente en modifiant simplement l’état parent dans le routeur ui:

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

Ajoutez angular-ui-router-default et ajoutez les options abstract et default à l’état parent:

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

Remarque: pour que cela fonctionne, le gabarit parent doit avoir quelque part.