AngularJSのUI-Routerを使用して状態をデフォルトのサブ状態にリダイレクトします


89

データを表示するタブベースのページを作成しています。AngularJsでUIルーターを使用して状態を登録しています。

私の目的は、ページの読み込み時に1つのデフォルトタブを開くことです。各タブにはサブタブがあり、タブを変更するときにデフォルトのサブタブを開いておきたいのですが。

私はonEnter関数でテストして$state.go('mainstate.substate');いましたが、内部では使用していますが、ループ効果の問題(state.goではサブステートから親ステートを呼び出すなど)が原因で機能しないようです。

$stateProvider

.state('main', {
  url: '/main',
  templateUrl: 'main.html',
  onEnter: function($state) {
    $state.go('main.street');
  }
})

.state('main.street', {
  url: '/street',
  templateUrl: 'submenu.html',
  params: {tabName: 'street'}
})

ここで私はプランカーのデモを作成しました

今のところ、デフォルトのタブを開いていないことを除いて、すべてが機能します。それがまさに私が必要としていることです。

提案、意見、アイデアをありがとうございます。

回答:


172

更新: 1.0以降そのままでredirectToをサポートします。

https://ui-router.github.io/ng1/docs/latest/interfaces/state.statedeclaration.html#redirectto


ここで例を作成しまし

この解決策は、素敵な「コメント」からリダイレクトを使用した問題.when() https://stackoverflow.com/a/27131114/1679310それに対する本当にクールな解決策(Chris Tによるものですが、元の投稿はyahyaKacemによるもの)です。

https://github.com/angular-ui/ui-router/issues/1584#issuecomment-75137373

それで、最初にリダイレクト設定でメインを拡張しましょう:

$stateProvider
    .state('main', {
      url: '/main',
      templateUrl: 'main.html',
      redirectTo: 'main.street',
    })

そして、この数行だけを実行に追加します

app.run(['$rootScope', '$state', function($rootScope, $state) {

    $rootScope.$on('$stateChangeStart', function(evt, to, params) {
      if (to.redirectTo) {
        evt.preventDefault();
        $state.go(to.redirectTo, params, {location: 'replace'})
      }
    });
}]);

このようにして、デフォルトのリダイレクトで任意の状態を調整できます... ここで確認してください

編集:ブラウザの履歴を保持するために、@ Alecによるコメントからオプションを追加しました。


4
これは戻るボタンをたたくようです。
Scott Sword

6
@ Swordfish0321で[戻る]ボタンを修正し、この小さな変更$state.go(to.redirectTo, params, {location: 'replace'});を行います。これにより、履歴の以前の状態(つまり、リダイレクト元の状態)が新しい状態に置き換わります。$ state.goのためのドキュメントを参照してください。angular-ui.github.io/ui-router/site/#/api/...
アレック・

2
ただ、これは簡単に変更することで達成された、これは私がやりたいことに本当の近くだったことに追加したいが、私は代わりにそれを置き換えるのデフォルトのURLを望んでいた'$stateChangeStart''$stateChangeSuccess'
マッティ価格

6
UI-ルータ1.0は、このためのサポートが組み込まれています:ui-router.github.io/guide/ng1/...
ゲルト・ヤン

21

実際、Radimによって提案されたこのソリューションが正確に機能したとしても、すべてのタブのサブタブ(状態)を覚えておく必要がありました。

だから私は同じことをするがすべてのタブサブステートを覚えている別の解決策を見つけました。

私がしなければならないのは、ui-router-extrasをインストールし、ディープステートリダイレクト機能を使用することだけでした。

$stateProvider
  .state('main.street', {
     url: '/main/street',
     templateUrl: 'main.html',
     deepStateRedirect: { default: { state: 'main.street.cloud' } },
  });

ありがとうございました!



7

ui-routerのバージョン1.0以降、http://angular-ui.github.io/ui-router/feature-1.0/のデータドリブンデフォルトサブステートの例に示されているように、IHookRegistry.onBefore()を使用してデフォルトフックが導入されています。interfaces / transition.ihookregistry.html#onbefore

// state declaration
{
  name: 'home',
  template: '<div ui-view/>',
  defaultSubstate: 'home.dashboard'
}

var criteria = {
  to: function(state) {
    return state.defaultSubstate != null;
  }
}
$transitions.onBefore(criteria, function($transition$, $state) {
  return $state.target($transition$.to().defaultSubstate);
});

私はそれを微調整しなければならなかった、が、私にとってはこの種の仕事、(もES6を使用)$transitions.onBefore({ to: state => state.defaultSubstate != null }, trans => trans.router.stateService.target(trans.to().defaultSubstate));
yorch

3
app.config(function($stateProvider,$urlRouterProvider){

    $urlRouterProvider.when("/state","/state/sub-state");

    })

1
これが何をするのか、なぜそれが既存の回答よりも優れているのかについての説明を提供できますか?
Equalsk 2017

このソリューションが最も簡単で、私にとってはうまくいきました。
BuffMcBigHuge

これは断然最良の答えです。変更イベントを使用するよりも簡潔です。パッケージを追加する必要はありません。どのようにそれが誰に明らかであるか私は知りません。受け入れられた回答がどのように賛成されたかはわかりません。
CodeWarrior

1

誰かが状態の単純なリダイレクトを実装する方法に関する答えを求めてここに来た場合、私がそうしたように、新しいルーターを使用する機会がありません...

言うまでもなく、可能であれば、@ bblackwoの答えは素晴らしいです:

$stateProvider.state('A', {
  redirectTo: 'B',
});

それができない場合は、手動でリダイレクトしてください:

$stateProvider.state('A', {
  controller: $state => {
    $state.go('B');
  },
});

お役に立てば幸いです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.