77 votes

Diriger l'utilisateur vers un état enfant lorsqu'il passe à l'état parent en utilisant UI-Router.

Considérez 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 à example.com/staff/1234/view comment puis-je passer à l'option par défaut manager.staffDetail.view.schedule l'état d'enfant ?

0 votes

Pour info, j'utilise actuellement le redirectTo méthode trouvée ici stackoverflow.com/questions/29491079/

0 votes

Veuillez NE PAS modifier ce document pour créer un code plus vertical. Le code est formaté spécifiquement pour montrer visuellement les états enfants en comparaison avec leurs parents.

0 votes

@UdayHiwarale c'est le même lien que celui déjà posté ci-dessus.

136voto

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

  2. Ensuite, faites un des éléments suivants :

  • Donnez à la 'manager.staffDetail.view.schedule' déclarer un URL vide . Ainsi, il correspondra à 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 voulez garder l'URL de la route enfant par défaut inchangée, alors configurez un fichier de type rediriger dans votre module.config . Ce code ici va rediriger n'importe quel emplacement de '/staff/{id}/view' à l'emplacement de '/staff/{id}/view/schedule' :

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

4 votes

Pour le $urlRouterProvider j'ai obtenu une erreur lors de l'utilisation d'un lien avec ui-sref="manager.staffDetail.view" donc j'ai dû enlever abstract: true de la déclaration d'état parent.

4 votes

La deuxième option ne fonctionnera pas pour les liens internes ui-sref (ils ne seront pas dirigés vers le substate).

20voto

rab Points 1807

Pour définir la vue enfant par défaut, vérifiez ceci exemple . En cliquant sur Route 1 charger 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"];
    }
  })

0 votes

Si route1.desc n'a pas d'url, vous pouvez quand même l'atteindre avec $state.go pero route1.list serait chargé par défaut sur /route1 :) c'est utile si vous ne voulez pas donner un accès direct à l'état via l'url.

2 votes

Il y a un gros problème avec ceci si nous voulons utiliser l'état parent dans ui-sref

0 votes

Vous devez utiliser href="http://stackoverflow.com/abstractroute" pour établir un lien avec le parent

9voto

Chuck D Points 322

J'ai rencontré le même problème et j'ai trouvé cette solution qui fonctionne :

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

Ceci est cité par @christopherthielen sur github

"Pour l'instant, ne déclarez pas votre état abstrait, 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 fonctionne le processus :

  1. L'utilisateur navigue vers l'état "parent".
  2. L'événement "$stateChangeStart" est déclenché.
  3. L'écouteur pour "$stateChangeStart" capte l'événement et transmet "toState" (qui est "parent") et "event" à la fonction du gestionnaire
  4. La fonction du gestionnaire vérifie si "redirectTo" est défini sur "toState".
  5. Si "redirectTo" N'EST PAS défini, rien ne se passe et l'utilisateur continue vers l'état "toState".
  6. Si "redirectTo" est défini, l'événement est annulé (event.preventDefault) et $state.go(toState.redirectTo) les envoie vers l'état spécifié dans "redirectTo" (qui est "parent.child").
  7. L'événement "$stateChangeStart" est à nouveau déclenché, mais cette fois-ci, "toState" == "parent.child" et l'option "redirectTo" n'est pas définie, de sorte qu'il se poursuit sur "toState".

7voto

nvcnvn Points 1378

Un peu tard mais je pense que vous pouvez "rediriger" 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.

3 votes

J'ai essayé, mais cela charge deux fois les contrôleurs, les résolus et tout ce qui est onStateChange. J'ai fini par utiliser $urlRouterProvider.when('/app/service', '/app/service/list').

0 votes

Est-ce que cela se chargera seulement deux fois ou une infinité de fois car l'état enfant invoque également l'état parent à nouveau car nous redirigeons à nouveau vers l'enfant.

0 votes

Si votre navigation comporte la sref parent, elle ne fonctionnera pas lors des clics suivants, mais uniquement lors du chargement initial du contrôleur.

3voto

Meeker Points 600

J'ai changé 'manager.staffDetial.view' en un état abstrait et laissé l'url de mon état enfant par défaut en blanc ''.

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

13 votes

Vous avez donc fait exactement ce que j'avais suggéré... pourquoi ne pas cocher ma réponse ? Pour que je puisse obtenir les points de fidélité.

0 votes

Je ne suis pas sûr que vous sachiez ce que signifie le mot "exactement". Cependant, votre exemple de code utilisait la méthode routeProvider. J'ai choisi de ne pas l'utiliser du tout et de garder la solution à l'intérieur du gestionnaire d'état. De cette façon, le code reste propre et n'ajoute pas de lignes de code supplémentaires inutiles. Votre exemple était une réponse possible, mais pas la réponse la plus acceptable.

0 votes

Il me semblait que tout ce que vous avez fait, je l'avais déjà mentionné (bien que, oui, le code dans mon exemple n'était pas nécessaire). MOI : "...tu devrais le mettre dans un état abstrait." VOUS : "J'ai changé 'manager.staffDetial.view' en un état abstrait..." MOI : "Ou une autre option est de donner au programme une URL vide." VOUS : "...et laissé l'URL de mon état enfant par défaut à vide". Sérieusement, sans rancune, je suis content que vous ayez trouvé la solution.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X