我不确定我这样做是否正确,任何建议都将不胜感激.
我有一个餐厅选择器,用户可以从中选择一家餐馆.然后所有其他子状态加载特定于所选餐厅的内容.但是我需要默认选择一个子状态,包括一个餐厅,根据用户最近的位置选择,或者如果他们之前选择了一个,则选择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: "", 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
我会创建一个每次打开特定状态时触发的事件.
看看他们的文档: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解决更多示例/更好的解释
我需要让它工作,所以要从@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部分,但条件和状态的改变是有效的.