我尽可能地把代码煮熟了.关于嵌套状态和事件处理/广播的事情导致无限循环.在Chrome中我可以暂停它并看到它在Angular的$digest函数中永远循环.知道为什么吗?这是我的示例代码中的错误,还是
Angular或
UI Router中的错误?
<!doctype html> <html ng-app='bugapp' ng-controller='BugAppCtrl'> <head> <script src='//code.jquery.com/jquery-1.10.1.min.js'></script> <!-- Angular 1.2.11 --> <script src='//ajax.googleapis.com/ajax/libs/angularjs/1.2.11/angular.js'></script> <!-- UI router 0.2.8 --> <script src='//cdn.jsdelivr.net/angular.ui-router/0.2.8/angular-ui-router.js'></script> <script> angular.module('bugapp',['ui.router']) .run(function ($rootScope,$state,$stateParams) { $rootScope.$state = $state; $rootScope.$stateParams = $stateParams; }) .config(function ($locationProvider,$stateProvider,$urlRouterProvider) { $locationProvider.html5Mode(false); $stateProvider .state("root",{ abstract: true,url: "/servletContext?asUser",template: '<div ui-view></div>' // ??? }) .state("root.home",url: "/home",template: "<div ng-if='hasData()' ui-view ></div>" }) .state("root.home.profile",{ url: "/profile",template: '<div>whatever</div>' }) }) .controller('BugAppCtrl',function ($scope,$stateParams,$log,$location) { $log.log('BugAppCtrl: constructor'); $scope.hasData = function() { var res = !!$scope.foo; // $log.log("hasData called,returing " + res + " foo is " + $scope.foo); return res; }; $scope.$on('$stateChangeSuccess',function () { $log.log("State changed! (to " + $state.current.name + ")"); $scope.foo = 'junk'; $scope.$broadcast("resetfoo"); }); $state.go('root.home.profile'); }); </script> </head> <body> <div ui-view></div> </body> </html>
解决方法
我怀疑这是UI路由器中的一个错误,原因有两个:
>我尝试了您的代码,然后尝试降级UI的版本
路由器到0.2.7.当我使用0.2.7时,它工作.
>即使您继续使用UI路由器的0.2.8版本,如果您通过$location而不是$state执行状态更改,它也可以.这是使用$location而不是$state.go调用的示例:
$location.path('/servletContext/home/profile');
虽然我使用并推荐UI路由器(不能没有嵌套视图),但如果您在将来发现当用户尝试转到某些页面时您想要进行任何类型的拦截或重定向,我建议使用$location.路径而不是$state,原因我描述了in a blog post
编辑:我之前没有尝试过参数,只是尝试了你发布的代码(我创建了第二个控制器,并将其分配给你的’root.home.profile’状态),它的工作原理. UI路由器的说明是here.但基本上如果您在状态定义中设置URL的方式与使用UI路由器的方式相同:
url: "/profile/:foo",
$location.path('/servletContext/home/profile/12');
你可以从控制器访问12
$stateParams.foo