Подтвердить что ты не робот

Как перенаправить к состоянию, если конкретный stateParam пуст

Я не уверен, правильно ли я это делаю, любые советы будут оценены.

У меня есть селектор ресторанов, с которого пользователь может выбрать ресторан. Затем все остальные дочерние состояния загружают контент, специфичный для выбранного ресторана. Но мне нужно, чтобы выбранное по умолчанию дочернее состояние включало в себя ресторан, который будет либо выбран на основе ближайшего местоположения пользователей, либо в данных cookie, если они ранее были выбраны. Но, я не уверен, как я могу перенаправить на дочернее состояние по умолчанию, не зная идентификатор ресторана уже?

Ниже приведена своя версия моего кода ниже.

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

4b9b3361

Ответ 1

Я бы создал событие, которое запускается каждый раз, когда вы открываете это конкретное состояние.

Проверьте их документ: https://github.com/angular-ui/ui-router/wiki#onenter-and-onexit-callbacks

Итак, я думаю, что-то вроде этого

1. onEnter callback to restaurant state (рекомендуется)

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

Это, вероятно, самое быстрое решение с точки зрения разработки, но я считаю, что использование событий является более чистым и делает более понятным код.

Примечание. Я действительно не запускал какой-либо из этого кода, поэтому он может не работать, это просто псевдокод, чтобы дать вам представление о том, куда идти. Дайте мне знать, если у вас возникнут проблемы.

EDIT: Я не уверен, переданы ли stateParams контроллеру. Возможно, вам придется использовать разрешение для доступа к ним.

EDIT: для доступа к stateParams в обратном вызове onEnter или контроллере, я считаю, что вам нужно использовать решение как таковое:

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

см. документ ui-router о решении для получения дополнительных примеров/лучшего объяснения

Ответ 2

Мне нужно было заставить это работать, поэтому, чтобы добавить подробности в ответ от @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 этого, но сработало условие и состояние.