切换到使用Browserify后,不会发出Angular UI路由器的$ stateChangeSuccess

时间:2016-03-31 14:53:33

标签: javascript angularjs angular-ui-router browserify

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

修改

我通过npm安装了angular-ui-router 1.0.0-alpha.1。我根据Chris的评论检查了角度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-router被要求进入应用程序的核心依赖项子模块

'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;

服务/ 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;

服务/ 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;

1 个答案:

答案 0 :(得分:2)

所以我设法通过使用他的评论中提到的$ transition.on *钩子Chris T来实现它。我还调查了这个$ 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');
    }
  }
})