使用ui-router(AngularJS)时,$ rootScope.$ on("$ routeChangeSuccess"或$ rootScope.$ on("$ stateChangeSuccess")不起作用

Kar*_*nna 7 angularjs angular-routing angular-ui-router

我在我的应用程序中使用UI路由器来嵌套视图,但同时我想在路由更改时监听事件.在使用UI路由器之前,routeChangeSuccess正好点火但是在ui-router之后它不会触发.文档建议使用viewContedLoaded或stateChangeSuccess,但即使他们不被解雇.我正在粘贴我的代码片段.任何帮助,将不胜感激.

var app = angular.module('SmartKart', ['ngCookies','ngRoute','ui.bootstrap','angularPayments','ngAnimate','toaster','ui.router','LocalStorageModule']);
app.config(['$routeProvider','$httpProvider','$urlRouterProvider', '$stateProvider',  function($routeProvider, $httpProvider,$urlRouterProvider,$stateProvider) {
$routeProvider
//TODO: Clean-up...most of these routes can be eliminated since we are now using nested views inside main.html. should probably use .otherwise(... main.html) or something
  .when('/postal',
  {
    templateUrl: 'static/partials/landingPage.html',
    requireLogin: false
  })
  .when('/register',
  {
    templateUrl:'static/partials/landingPage.html',
    requireLogin: false
  })
  .when('/login',
  {
    templateUrl:'static/partials/landingPage.html',
    requireLogin: false
  })
  .when('/forgot',
  {
    templateUrl:'static/partials/landingPage.html',
    requireLogin: false
  })
  //TODO: Clean-up...most of these routes can be eliminated since we are now using nested views inside main.html
  .when('/noregister',
  {
    templateUrl:'static/partials/landingPage.html',
    requireLogin: false
  })
  .when('/contact',
  {
    templateUrl:'static/partials/contact.html'
  })
  .when('/home',
  {
    templateUrl:'static/partials/main.html',
    requireLogin: true
  })
  .when('/productList', //so routeProvider will load main.html, stateProvider will load the product list nested view
  {
    templateUrl:'static/partials/main.html',
    requireLogin: true
  })
  .when('/searchResults', //so routeProvider will load main.html, stateProvider will load the product list nested view
  {
    templateUrl:'static/partials/main.html',
    requireLogin: true
  })
  .when('/products/:storeId',
  {
    templateUrl:'static/partials/main.html',
    requireLogin: true    
  })
  .when('/products/store/:storeId/department/:departmentId/aisle/:aisleId',
  {
    templateUrl:'static/partials/main.html',
    requireLogin: true    
  })
  // .when('/productDetail/:productId',
  // {
  //   templateUrl:'static/partials/productDetail.html' ,
  //   requireLogin: true
  // })
  .when('/checkout',{
    templateUrl:'static/partials/page.html',
    requireLogin: true
  })
  .when('/jobrequest',{
    templateUrl:'static/partials/driverJobRequest.html'
  })
  .when('/orders',{
    templateUrl:'static/partials/page.html', //stateProvider will load the Orders list as a nested view within the main html
    requireLogin: true
  })
  .when('/admin',{
    templateUrl:'static/partials/main.html'
  })
  .when('/reset',{
    templateUrl:'static/partials/resetPassword.html'
  })
  .when('/changePassword',{
    templateUrl:'static/partials/changePassword.html',
    requireLogin: false
  })
  .when('/driver/:orderNumber',{
    templateUrl:'static/partials/main.html',
    requireLogin: false
  })
  .when('/driver',{
    templateUrl:'static/partials/main.html',
    requireLogin: false
  })
  .when('/profilepage',{
    templateUrl:'static/partials/profilePage.html',
    requireLogin: false
  })
  .when('/', {
    templateUrl : 'static/partials/landingPage.html', 
    requireLogin: false
  });

   $httpProvider.defaults.useXDomain = true;
   delete $httpProvider.defaults.headers.common['X-Requested-With'];
   $httpProvider.defaults.withCredentials = true;

  //Used for controlling nested views inside main.html and page.html
  $stateProvider 
    .state('products', {
        url: "/productList",
        templateUrl: "static/partials/productList.html",
        controller: 'ProductListCtrl'
    })
    .state('searchResults', {
        url: "/searchResults",
        templateUrl: "static/partials/searchResults.html",
        controller: 'ProductSearchResultsCtrl'
    })
    .state('orders', {
        url: "/orders",
        templateUrl: "static/partials/orderList.html",
        controller: 'UserOrderListCtrl'

    })        
    .state('checkout', {
        url: "/checkout",
        templateUrl: "static/partials/checkout.html",
        controller: 'checkoutCtrl'
    })

    .state('admin', {
        url: "/admin",
        templateUrl: "static/partials/admin.html",
        controller: 'AdminCtrl'
    })
    .state('driver', {
        url: "/driver",
        templateUrl: "static/partials/driverDashboard.html",
        controller: 'DriverDashboardCtrl'
    })
    .state('driverOrder', { //gets assigned order for this number
        url: "/driver/:orderNumber",
        templateUrl: "static/partials/singleOrder.html",
        controller: 'OrderCtrl',
        resolve: {
          order: function($stateParams) {
          return $stateParams.orderNumber;
             }
         }
    });

  }]);


app.run(['$rootScope', '$location' ,'$cookieStore', '$state', 'CacheManager',  function($rootScope, $location, $cookieStore, $state,CacheManager){

 //(re)load cached values here
 //CacheManager.loadCache();

 $rootScope.$on(['stateChangeStart', function(){
 alert('hello1');
 var urlCheck1 = $location.path() != '/forgot' && $location.path() != '/register' &&   $location.path() != '/postal' && $location.path() != '/';
  var urlCheck2 = $location.path() != '/jobrequest';
   if(urlCheck1 && urlCheck2){
     if($cookieStore.get('userToken') == undefined){
        $location.path('/login');
        //seems insufficient to only check if the userToken is defined to go through here. we should check that it's == XCSRF token?
     } else if($cookieStore.get('userToken') != undefined && ($location.path() == '/login' || $location.path() == '/')){
        $location.path('/home');
     }
  }
  if ($rootScope.cartItems.length > 0){
  showCart();
}

  }]);


}]);
Run Code Online (Sandbox Code Playgroud)

Mat*_*lis 9

你的代码中的两件事对我来说很奇怪,这可能会导致问题(然后再次,因为我只能看到你的一些代码,我可能是错的).

  1. 你这样做的方式:

    if ($location.path() == '/orders'){
      $state.go('orders');
    } else if ($location.path() == '/admin'){
      $state.go('admin');
    } else if ($location.path() == '/productList'){
      $state.go('products');
    } else if ($location.path() == '/driver'){
      $state.go('driver');
    } else if ($location.path() == '/driverOrder/:orderNumber'){
      $state.go('driverOrder');
    }  else if ($location.path() == '/driverOrder/:orderNumber'){
      $state.go('checkout');
    }
    
    Run Code Online (Sandbox Code Playgroud)

    如果您在配置块中设置状态(如UI路由器示例显示),似乎不应该这样做 - 请参阅此链接并向下滚动到步骤(5).(另外,你的最后两个else-if语句在if语句中有相同的子句,所以'$ state.go('checkout');'永远不会被执行.)

  2. 因为基于$ location.path()将用户发送到不同状态的那个块位于您注册监听器的位置上方,所以您的应用程序甚至可能无法执行您尝试注册监听器的行.我会尝试将监听器注册移到那个大的if/else块之上.另外,我同意Phil Thomas在评论中提出的建议,你应该至少听取$ stateChangeStart,直到你确定正确注册了监听器,因为其他问题可能会阻止$ stateChangeSuccess.

编辑:此外,鉴于您最近的编辑,您的stateChangeStart侦听器看起来不正确.您注册监听器的方式应该是这样的:

$rootScope.$on('$stateChangeStart', 
function(event, toState, toParams, fromState, fromParams){ 
    // logic
})
Run Code Online (Sandbox Code Playgroud)

此外,在侦听器内部,不要使用$ location,只使用您作为侦听器参数给出的内容.例如,查看toState以查看用户尝试去的位置.这样做的原因是,在转换过程中,你需要找到用户试图去的地方,而$ location会告诉你用户已经在哪里.