如果特定stateParam为空,如何重定向到状态

时间:2013-12-17 18:08:19

标签: angularjs angular-ui-router

我不确定我这样做的方式是否正确,任何建议都会受到赞赏。

我有一个餐厅选择器,用户可以从中选择一家餐馆。然后所有其他子状态加载特定于所选餐厅的内容。但我需要默认选择一个子状态,包括一个餐厅,根据用户最近的位置选择,如果他们之前选择了一个,则选择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

2 个答案:

答案 0 :(得分:38)

我会创建一个每次打开特定状态时触发的事件。

查看他们的文档: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'])
    }
}]

这可能是开发方面最快的解决方案,但我相信使用事件更清晰,可以使代码更容易理解。

注意:我实际上没有运行任何此类代码,因此它可能无法正常工作,它只是伪代码,可以让您了解要去哪里。如果您遇到问题,请告诉我。

编辑:实际上我不确定stateParams是否传递给控制器​​。您可能必须使用resolve来访问它们。

编辑:要在onEnter回调或控制器中访问stateParams,我相信你必须这样使用resolve:

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

请参阅ui-router doc解决更多示例/更好的解释

答案 1 :(得分:5)

我需要让这个工作,所以要从@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部分,但条件和状态的变化都有效。