2013-12-17 9 views
27

私が行っているやり方が正しいかどうか分かりませんが、助言をいただければ幸いです。特定のstateParamが空である場合にリダイレクトする方法

私はレストランセレクタを用意しています。レストランセレクタを使用してレストランを選択できます。他のすべての子ステートは、選択したレストランに固有のコンテンツを読み込みます。しかし、私は子供の状態をデフォルトで選択する必要があります。レストランはユーザーの最も近い場所に基づいて選択されるか、以前に選択された場合にはCookieデータに基づいて選択されます。しかし、私はすでにレストランのIDを知らなくても、デフォルトでどのように子供の状態にリダイレクトできるのか分かりません。

説明するために私のコードの暗黙のバージョンです。

app.config(function ($stateProvider, $urlRouterProvider) { 
$urlRouterProvider.otherwise("/restaurant/[some id based on cookie info]/our-food"); // if no id is set, then I want to get it from a cookie, but then how do i do the redirect? 

$stateProvider 
    .state('restaurant', { 
     url: '/restaurant/:restaurantId', 
     template: "<ui-view/>", 
     controller: function($state, $stateParams, Data, RestaurantService, $cookieStore) { 
      if(typeof $stateParams.restaurantId !== 'undefined') { 
            // get the restaurantID from the cookie 
          } 
     } 
    }) 
    .state('restaurant.our-food', { 
     url: '/our-food', 
     templateUrl: function($stateParams) { 
     return 'templates/food-food.html?restaurantId=' + $stateParams.restaurantId; 
     }, 
    controller: 'SubNavCtrl' 
    }) 
    .state('restaurant.glutenfree-vegetarian', { 
     url: '/glutenfree-vegetarian', 
     templateUrl: function($stateParams) { 
    return 'templates/food-vegetarian.html?restaurantId=' + $stateParams.restaurantId; 
     }, 
    controller: 'SubNavCtrl' 
    }) 

フロントエンドで何が起こっているかを説明するには、以下の画像は: www.merrywidowswine.com/ss.jpg

答えて

37

私はあなたがその特定の状態を開くたびに発射されたイベントを作成します。

は自分のドキュメントをチェックアウト:https://github.com/angular-ui/ui-router/wiki#onenter-and-onexit-callbacks

は、だから私の推測では、私は使ったことがないのいずれかのレストランの状態(推奨)

$stateProvider.state("contacts", { 
    template: '<ui-view>', 
    resolve: ..., 
    controller: function($scope, title){ 
    }, 
    onEnter: function(){ 
    if(paramNotSet){ $state.go(...)} 
    } 
}); 

へのコールバックフォーカス取得時、この

1のようなものですこのような自分自身のような出来事で解決のために何か体操をしなければならないかもしれないが、これは最もクリーンで、理解しやすく、最も保守的な解決策であると私は信じている。

2グローバルonStateChangeStartイベント コントローラ代わり でグローバルイベント(これは、すべての状態変化のために解雇になるだろうが)

$rootScope.$on('$stateChangeStart', 
function(event, toState, toParams, fromState, fromParams){ ... //check cookie, change state etc ...}) 

3あなたが開始したように、コントローラを使用したい場合やって

controller: ['$state', '$stateParams', 'Data', 'RestaurantService', '$cookieStore', 
function($state, $stateParams, Data, RestaurantService, $cookieStore) { 
    if(typeof $stateParams.restaurantId !== 'undefined') { 
     sate.go('restaurant', $cookieStore['restaurant']) 
    } 
}] 

これはおそらく開発の点で最も速い解決策ですが、私はイベントの使用がよりクリーンで理解しやすいコードになると考えています。

注:実際にはこのコードを実行していないため、動作しない可能性があります。どこに行くかを擬似コードで示しています。あなたが問題にぶつかったら教えてください。

EDIT:stateParamsがコントローラに渡されるかどうかはっきりとはわかりません。解決にはアクセスする必要があります。

EDIT:フォーカス取得時のコールバックまたはコントローラでアクセスstateParamsに、私はあなたのような決意を使用するために持っていると信じています:

resolve: { 
     checkParam: ['$state','$stateParams', '$cookieStore', function($state, $stateParams, $cookieStore) { 
//logic in here, what it returns can be accessed in callback or controller. 
     }] 

より多くの例/より良い説明のための解決にUI-ルータのドキュメントを参照してください

+0

ありがとう、それは正しい方向に私を指し示す、私は遊びを持って、私はそれがすべて働くことができるかどうかを見るつもりです。乾杯! –

+1

#1解決策の問題は、onEnterが実行される前にすべての解決プロパティが解決されるということです。私はgithubに関する問題を始めました:https://github.com/angular-ui/ui-router/issues/1102。リダイレクトする前に解決されたパラメータを解決したくない場合(たとえば、ルートに特定のパラメータが必要な場合)、短絡する隠れフックがあるかどうかはわかりません。 – Beez

+0

'$ state.transitionTo'の代わりに' $ state.go'を使う方がいいかもしれません、[here](https://github.com/angular-ui/ui-router/wiki/Quick-Reference##) state-1) – Daniele

3

私はそう@NicolasMoiseからの回答に詳細を追加するために、この作業を取得するために必要な:

.state('restaurant', { 
    url: '/restaurant/:restaurantId', 
    template: "<ui-view/>", 
    onEnter: function ($state, $stateParams, $cookies) { 
     console.log($stateParams.restaurantId); 
     if (!$stateParams.restaurantId) { 
     $stateParams.restaurantId = $cookies.restaurantId; 
     $state.go('restaurant.restaurantID'); 
     } 
    }, 
}) 

Iこれのクッキー部分をテストしませんでしたが、条件付きと状態の変更が機能しました。

関連する問題