我正在尝试实施用户身份验证系统。我读过401
http状态代码和HTTP Auth Interceptor Module。
我已经用bower下载了该模块并将其加载到我的app模块中。我还没有使用它,但是当用户在浏览器中打开应用程序时,我想使用此模块触发的相同事件来显示用户登录弹出窗口。
我的所有控制器都是CoreController
的孩子。 CoreController
解析当前用户。当应用程序加载时没有用户登录,因此我想显示发出事件的登录表单:event:auth-loginRequired
(与http-auth-interceptor相同)。
在此CoreController
中,我有另一条规则正在侦听此特定事件(event:auth-loginRequired
)。如果检测到此事件,控制器将显示弹出窗口,调用其state
id。
我遇到的问题是控制台说我已经正确地发出了事件,但我的监听器没有被触发,因此登录弹出窗口没有显示。
这是我的CoreController
:
/**
* Index controller definition
*
* @scope Controllers
*/
define(['./../module', 'moment'], function (controllers, moment) {
'use strict';
controllers.controller('CoreController', ['$scope', '$rootScope', '$state', 'user', function ($scope, $rootScope, $state, user)
{
console.log('Core Controller Loaded');
$scope.loader = true;
$scope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams)
{
$scope.loader = true;
});
$scope.$on('event:auth-loginRequired', function(event, toState, toParams, fromState, fromParams)
{
console.log('catch auth required');
$state.go("main.login");
});
if (user.isLogged == false) {
console.log('emit auth required');
$rootScope.$emit('event:auth-loginRequired');
}
}]);
});
我做错了什么?
干杯, 马克西姆
答案 0 :(得分:8)
问题是您在$rootScope
上发光,该事件无法到达您当地的$scope
听众。
轻松出路(不推荐):
if (user.isLogged == false) {
console.log('broadcast auth required');
$rootScope.$broadcast('event:auth-loginRequired');
}
此解决方案的问题在于,事件会从您的$rootScope
向下冒泡到您的所有子范围。从性能的角度来看,这并不好。
更好的出路(推荐):
$rootScope.$on('event:auth-loginRequired', function(event, toState, toParams, fromState, fromParams)
{
console.log('catch auth required');
$state.go("main.login");
});
if (user.isLogged == false) {
console.log('emit auth required');
$rootScope.$emit('event:auth-loginRequired');
}
我们在$rootScope
设置事件监听器,而$emitting
为$rootScope
- 事件不会遍历您的$ scope层次结构并导致性能问题。
另一种方式,这是我从控制器处理$ rootScope事件监听器的首选方法,是在销毁本地$ scope时取消订阅事件监听器。
更好的出路(强烈推荐(在我看来*)):
var mainModule = angular.module('myModule'); // this would be your core module, tying everything together.
mainModule.config(function ($provide) {
// Define an alternative to $rootScope.$on.
// $scope.subscribe will emulate the same behaviour, with the difference
// of removing the event listener when $scope.$destroy is called.
$provide.decorator('$rootScope', function ($delegate) {
Object.defineProperty($delegate.constructor.prototype, 'subscribe', {
value: function (name, listener) {
var unsub = $delegate.$on(name, listener);
this.$on('$destroy', unsub);
},
enumerable: false
});
return $delegate;
});
});
// Then in your CoreController
$scope.subscribe('event:auth-loginRequired', function(event, toState, toParams, fromState, fromParams)
{
console.log('catch auth required');
$state.go("main.login");
});
if (user.isLogged == false) {
console.log('emit auth required');
$rootScope.$emit('event:auth-loginRequired');
}
这也是如此,您不再需要将$rootScope
注入控制器以设置$rootScope
侦听器(但这不适用于设置发射器)。
无论你决定解决这个问题,我都强烈建议你研究解决方案#2或#3。 #1绝对不是我推荐的东西。
祝你好运!