Direcionando o usuário para um estado filho quando estão fazendo a transição para seu estado pai usando o roteador de interface do usuário

Considere o seguinte:

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

Se eu for para domain.com/staff/1234/view , como faço para usar como padrão o estado filho manager.staffDetail.view.schedule ?

  1. Primeiro, adicione uma propriedade ao estado 'manager.staffDetail.view' do abstract:true . Isso não é necessário, mas você quer definir isso, já que você nunca iria para esse estado diretamente, você sempre iria para um dos seus estados filhos.

  2. Em seguida, siga um destes procedimentos:

    • Dê ao 'manager.staffDetail.view.schedule' um URL vazio . Isso fará com que ele corresponda ao mesmo URL que o URL de estado pai, porque não acrescenta nada ao URL pai.

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

    • Ou, se você quiser manter a url da rota-filha padrão inalterada, configure um redirecionamento no seu module.config. Este código aqui redirectá qualquer localização de '/staff/{id}/view' para a localização de '/staff/{id}/view/schedule' :

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

Para definir a vista filho padrão, verifique este exemplo . Ao clicar em Route 1 carregue o estado padrão 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"]; } }) 

Eu encontrei o mesmo problema e encontrei esta solução para funcionar:

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

Isso é citado de @christopherthielen no github

“Por enquanto, não declare seu resumo de estado e use esta receita:”

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

Aqui está o detalhamento de como o processo funciona:

  1. Usuário navega para o estado “pai”
  2. Evento “$ stateChangeStart” é demitido
  3. O ouvinte de “$ stateChangeStart” captura o evento e passa “toState” (que é “pai”) e “evento” para a function de manipulador
  4. A function do manipulador verifica se “redirectTo” está definido em “toState”.
  5. Se “redirectTo” NÃO estiver definido, nada acontecerá e o usuário continuará no estado “toState”.
  6. Se “redirectTo” estiver definido, o evento é cancelado (event.preventDefault) e $ state.go (toState.redirectTo) os envia ao estado especificado em “redirectTo” (que é “parent.child”).
  7. O evento “$ stateChangeStart” é acionado novamente, mas desta vez “toState” == “parent.child” e a opção “redirectTo” não está definida, então continua a “toState”.

Muito tarde, mas acho que você pode “redirect” para o estado que você deseja.

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

Você pode escrever seu controlador diretamente na configuração de estado.

Mudei ‘manager.staffDetial.view’ para um estado abstrato e deixei a url do meu estado filho padrão em branco ”

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

Em “angular-ui-router”: “0.2.13”, eu não acho que a solução de redirecionamento do @ nfiniteloop funcionará. Funcionou assim que eu voltei para 0.2.12 (e posso ter que colocar a chamada $ urlRouterProvider.when antes do $ stateProvider?)

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

e https://stackoverflow.com/a/27131114/1098564 para uma solução alternativa (se você não quiser voltar para 0.2.12)

a partir de 28 de novembro de 2014, https://github.com/angular-ui/ui-router/issues/1584 indica que deve funcionar novamente em 0.2.14

Isso é tarde, mas todas as respostas aqui não se aplicam à versão mais recente do angular-ui-router para o AngularJS. A partir dessa versão (especificamente @ uirouter / angularjs # v1.0.x você pode apenas colocar redirectTo: 'childStateName' no segundo parâmetro de $stateProvider.state() . Por exemplo:

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

Aqui está a seção de documentos relevantes: https://ui-router.github.io/guide/ng1/migrate-to-1_0#state-hook-redirectto

Espero que isso ajude alguém!

Aqui está uma alternativa muito simples e transparente, apenas modificando o estado pai no roteador 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: '....' }) 

Adicione angular-ui-router-default e adicione as opções abstract e default ao estado pai:

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

Nota: para isso funcionar, o modelo pai deve ter em algum lugar nele.