2013-12-17 26 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

所以我的猜测是,要么像这样

1的OnEnter回调餐厅状态(推荐)

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

我从来没有使用事件本身就是这样,所以你可能不得不做一些体操运动,但我相信这是最清晰,最容易理解和最可维护的解决方案。

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

这可能是在发展方面最快的解决办法,但我相信使用事件是更清洁,让更多的可以理解的代码。

注意:我没有真正运行这些代码,所以它可能不起作用,它只是伪代码,让你知道该去哪里。如果遇到问题,请告知我。

编辑:Acutally我不知道是否stateParams传递给控制器​​。您可能必须使用解析来访问它们。

编辑:访问的OnEnter回调或控制器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#状态-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'); 
     } 
    }, 
}) 

我没有测试这个cookie的部分,但条件和状态的变化工作。

相关问题