web-dev-qa-db-ja.com

ユーザーがUIルーターを使用して親状態に移行するときに子状態に誘導する

以下を考慮してください。

.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子状態にデフォルト設定するにはどうすればよいですか?

76
Meeker
  1. まず、プロパティを'manager.staffDetail.view'abstract:true状態に追加します。これは必須ではありませんが、この状態に直接移動することはなく、常にその子状態のいずれかに移動するため、これを設定する必要があります。

  2. 次に、次のoneを実行します。

    • 'manager.staffDetail.view.schedule'状態に空のURLを指定します。これにより、親URLに何も追加されないため、親状態のURLと同じURLに一致します。

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

    • または、デフォルトの子ルートのURLを変更しない場合は、module.configでredirectを設定します。このコードは、'/staff/{id}/view'の場所を'/staff/{id}/view/schedule'の場所にリダイレクトします。

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

136
Tim Kindberg

デフォルトの子ビューを設定するには、この example を確認してください。 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"];
    }
  })
20
rab

私は同じ問題に遭遇し、この解決策が機能することがわかりました:

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. 「$ stateChangeStart」のリスナーはイベントをキャッチし、「toState」(「parent」)と「event」をハンドラー関数に渡します
  4. ハンドラー関数は、「reStateTo」が「toState」に設定されているかどうかを確認します。
  5. 「redirectTo」IS NOTが設定されている場合、何も起こらず、ユーザーは「toState」状態に進みます。
  6. 「redirectTo」ISが設定されている場合、イベントはキャンセルされ(event.preventDefault)、$ state.go(toState.redirectTo)は「redirectTo」で指定された状態(「parent.child」)にそれらを送信します)。
  7. 「$ stateChangeStart」イベントが再び発生しますが、今回は「toState」==「parent.child」で、「redirectTo」オプションが設定されていないため、「toState」に進みます。
8
Chuck D

かなり遅いですが、あなたが望む状態に「リダイレクト」できると思います。

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

略してstate configにコントローラーを書くことができます。

7
nvcnvn

「manager.staffDetial.view」を抽象状態に変更し、デフォルトの子状態のURLを空白のままにしました ''

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

「angular-ui-router」:「0.2.13」では、@ nfiniteloopのリダイレクトソリューションが機能するとは思わない。 0.2.12にロールバックすると機能しました($ stateProviderの前に$ urlRouterProvider.when呼び出しを配置する必要があったかもしれません)。

https://stackoverflow.com/a/26285671/1098564 を参照してください

および https://stackoverflow.com/a/27131114/1098564 回避策(0.2.12に戻りたくない場合)

2014年11月28日、 https://github.com/angular-ui/ui-router/issues/1584 は、0.2.14で再び動作することを示します

1
sdoxsee

これは遅いですが、ここでのすべての答えは、AngularJSのangle-ui-routerの最新バージョンには当てはまりません。 thatバージョン(具体的には @ uirouter/angularjs#v1.0.x の場合、redirectTo: 'childStateName'$stateProvider.state()の2番目のパラメータで、たとえば:

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

関連ドキュメントセクションは次のとおりです。 https://ui-router.github.io/guide/ng1/migrate-to-1_0#state-hook-redirectto

これが誰かの助けになることを願っています!

1
AndyPerlitch

angular-ui-router-default を追加し、abstractおよびdefaultオプションを親状態に追加します。

...

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

...

注:これが機能するには、親テンプレートのどこかに<ui-view/>が必要です。

0
Jonathon Hill

これは、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: '....'
  })
0
okigan