Angular UI路由器's$stateChangeSuccess在切换到使用Browserify后未发出

Angular UI Router's $stateChangeSuccess not being emitted after switching to using Browserify

本文关键字:Browserify 路由器 UI stateChangeSuccess Angular      更新时间:2023-10-07

我有一个Angular 1.5.x应用程序,它使用Angular UI Router的$stateChangeSuccess事件来注册一个侦听器,该侦听器验证用户是否在每次状态更改时登录以保护应用程序的某些视图。通过Browserify将应用程序移植到CommonJS环境后,注册的事件处理程序不再执行,但UI Router会像以前一样不断更改状态。我需要帮助弄清楚UI路由器是否以及为什么没有发出事件,或者问题是否是由在CommonJS环境中工作时Angular作用域的行为不同引起的。非常感谢您的帮助,谢谢!

编辑

我通过npm安装了angular ui路由器1.0.0-alpha.1。我根据Chris的评论查看了angular ui路由器github发布的文档,并决定通过恢复到0.2.18来看看它是否有效,但没有。

app.js

唯一需要的相关性声明是路线、核心和服务模块。

'use strict';
var angular = require('angular');
var routes = require('./app.routes.js');
// Sub-module Dependencies 
var core       = require('./app.core.js');
var services   = require('./services');
var layout     = require('./layout');
var auth       = require('./authentication');
var landing    = require('./landing');
var dashboard  = require('./dashboard');
var userManual = require('./user-manual');
// Define Angular Module
var app = angular.module('app', [
  core,
  services,
  layout,
  auth,
  landing,
  dashboard,
  userManual
])
.config(html5ModeTrue)
.config(routes)
.run(runBlock);
////////////////
html5ModeTrue.$inject = ['$locationProvider'];
runBlock.$inject = ['authService'];
////////////////
function html5ModeTrue ($locationProvider) {
  $locationProvider.html5Mode(true);
}
function runBlock(authService) {
  authService.initialize();
}

app.routes.js

'use strict';
routes.$inject = ['$stateProvider', '$urlRouterProvider'];
function routes($stateProvider, $urlRouterProvider) {
  $urlRouterProvider.otherwise("/");
  $urlRouterProvider.when('/dashboard', '/dashboard/analysis');
  $stateProvider
    .state('home', {
      url: "/",
      templateUrl: "app/landing/home.html"
    })
    .state('about', {
      url: "/about",
      templateUrl: "app/landing/about.html"
    })
    .state('atlas', {
      url: "/atlas",
      templateUrl: "app/landing/atlas.html"
    })
    .state('login', {
      url: "/login",
      templateUrl: "app/authentication/login.html",
      controller: "LoginController",
      controllerAs: "login"
    })
    .state('dashboard', {
      abstract: true,
      // url: "/dashboard",
      templateUrl: "app/dashboard/dashboard.html",
      controller: "DashboardController",
      controllerAs: "dash",
      restricted: true,
    })
    .state('dashboard.analysis', {
      url: "/dashboard/analysis",
      templateUrl: "app/dashboard/dashboard.analysis.html"
    })
    .state('dashboard.vmod', {
      url: "/dashboard/vmod",
      templateUrl: "app/dashboard/dashboard.vmod.html"
    })
    .state('dashboard.datasets', {
      url: "/dashboard/datasets",
      templateUrl: "app/dashboard/dashboard.datasets.html"
    })
    .state('dashboard.defaults', {
      url: "/dashboard/defaults",
      templateUrl: "app/dashboard/dashboard.defaults.html"
    })
    .state('dashboard.user-management', {
      url: "/dashboard/user-management",
      templateUrl: "app/dashboard/dashboard.user-management.html"
    })
    .state('user-manual', {
      url: "/user-manual",
      templateUrl: "app/user-manual/user-manual.html",
      restricted: true
    })
    .state('user-manual.analysis', {})
    .state('user-manual.vmod', {})
    .state('user-manual.datasets', {});
}
module.exports = routes;

app.core.js

如下所示,通过npm安装的angular ui路由器被要求进入应用程序的核心依赖项子模块

'use strict';
// Module Dependencies
require('angular-animate');       // ngAnimate
require('angular-ui-bootstrap');  // ui.bootstrap
require('angular-ui-router');     // ui.router
require('ui-leaflet');            // ui-leaflet
require('leaflet');               // Dependency for ui-leaflet
require('angular-simple-logger'); // Dependency for ui-leaflet
// Define Angular Module
var name = 'app.core';
require('angular').module(name, [
  'ui.bootstrap',
  'ui.router',
  'ngAnimate',
  'ui-leaflet',
]);
// Expose Angular Module Name For Easy Injection
module.exports = name;

services/index.js

这个文件只是作为需要应用程序的Angular服务的入口点。

'use strict';
// Module Dependencies
var authService = require('./auth.service.js');
var userManagementService = require('./user-management.service.js');
// Define Angular Module
var name = 'app.services';
require('angular')
  .module(name, [])
  .factory('authService', authService)
  .factory('userManagementService', userManagementService);
module.exports = name;

services/auth.service.js

该服务中的initialize函数为$stateChangeSuccess事件注册了一个侦听器,该侦听器从未被调用。

'use strict';
authService.$inject = ['$q', '$window', '$http', '$rootScope', '$location'];
function authService ($q, $window, $http, $rootScope, $location) {
  var userSession = null;
  var service = {
    initialize: initialize,
    isLoggedIn: isLoggedIn,
    getUserSession: getUserSession,
    login: login,
    logout: logout
  };
  return service;
  ////////////////
  function initialize() {
    var accessToken = $window.sessionStorage["fa-session"];
    userSession = accessToken ? JSON.parse(accessToken) : null;
    $rootScope.$on('$stateChangeSuccess', onStateChangeSuccess);
    function onStateChangeSuccess(event, toState, fromState, fromParams) {
      if (toState.restricted && isLoggedIn() === false) {
        $location.path('/login');
      }
    }
  }
  function isLoggedIn() {
    return userSession || false;
  }
  function getUserSession() {
    return userSession;
  }
  function login(username, password) {
    var deferred = $q.defer();
    $http.post('/api/login', {username: username, password: password})
      .then(loginComplete)
      .catch(loginFailed);
    return deferred.promise;
    function loginComplete(response) {
      userSession = {
        accessToken: response.data.access_token,
        username: response.data.username
      };
      $window.sessionStorage["fa-session"] = JSON.stringify(userSession);
      deferred.resolve(userSession);
    }
    function loginFailed(error) {
      deferred.reject(error);
    }
  }
  function logout() {
    var deferred = $q.defer();
    $http.post('/api/logout', {headers: {access_token: userSession.accessToken}})
      .then(logoutCompleted)
      .catch(logoutFailed);
    return deferred.promise;
    function logoutCompleted(response) {
      userSession = null;
      $window.sessionStorage["fa-session"] = null;
      deferred.resolve(response);
    }
    function logoutFailed(error) {
      deferred.reject(error);
    }
  }
}
module.exports = authService;

所以我设法通过使用Chris T在评论中提到的$transition.on*hooks使其工作。我还调查了$rootScope问题是否发生在状态更改事件之外。根据我所能验证的,$scope和$rootScope事件发射器和处理程序与我的控制器配合得非常好。

我更改了这个:

.state('user-manual', {
  url: "/user-manual",
  templateUrl: "app/user-manual/user-manual.html",
  restricted: true
})

在authService内部的偶数侦听器使用受限属性的情况下:

.state('user-manual', {
  url: "/user-manual",
  templateUrl: "app/user-manual/user-manual.html",
  // restricted: true
  onEnter: function (authService, $location) {
    if (!authService.isLoggedIn()) {
      $location.path('/login');
    }
  }
})