我不确定我这样做的方式是否正确,任何建议都会受到赞赏。
我有一个餐厅选择器,用户可以从中选择一家餐馆。然后所有其他子状态加载特定于所选餐厅的内容。但我需要默认选择一个子状态,包括一个餐厅,根据用户最近的位置选择,如果他们之前选择了一个,则选择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
答案 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部分,但条件和状态的变化都有效。