我在$rootScope
中将变量设置为true。此变量名为loggedIn
。
我创建了一个NavController来控制主菜单链接的显示,正如您所看到的,我正确地注入了$rootScope
。
appControllers.controller("NavController", function($rootScope, $scope) {
console.log($rootScope); //We can see that loggedIn is true
console.log($rootScope.loggedIn); //Outputs false
//Not working as expected
if($rootScope.loggedIn === true){
$scope.showHomeMenu = false;
$scope.showGameMenu = true;
$scope.currentHome = '/lobby';
}
else {
$scope.showHomeMenu = true;
$scope.showGameMenu = false;
$scope.currentHome = '/login';
}
});
奇怪的是,这不起作用,因为$rootScope.loggedIn
被评估为false
,即使它的值设置为true
。这是我从控制台获得的输出。
正如您从$rootScope
输出中看到的那样,loggedIn
应为true
。但它被评估为控制器中的false
。
我想我在做一些非常愚蠢的事情,但我无法弄明白为什么!!
修改2
@rvignacio指出了一些有趣的东西。我看到的对象$rootScope
是扩展时对象的状态,而不是我调用log()时的状态。
(这是可以预测的......)
我想这个问题比我想象的更深!我必须挖掘才能找到错误!
修改
我在run()
中设置了loggedIn。
app.config(function($routeProvider, $httpProvider) {
$routeProvider.
when('/', {
...
}).
...
});
var interceptor = ['$rootScope', '$q',
function(scope, $q) {
function success(response) {
return response;
}
function error(response) {
var status = response.status;
if (status == 401) {
var deferred = $q.defer();
var req = {
config: response.config,
deferred: deferred
};
scope.$broadcast('event:loginRequired');
return deferred.promise;
}
// otherwise
return $q.reject(response);
}
return function(promise) {
return promise.then(success, error);
};
}
];
$httpProvider.responseInterceptors.push(interceptor);
}).run(['$rootScope', '$http', '$location',
function(scope, $http, $location) {
/**
* Holds page you were on when 401 occured.
* This is good because, for example:
* User goes to protected content page, for example in a bookmark.
* 401 triggers relog, this will send them back where they wanted to go in the first place.
*/
scope.pageWhen401 = "";
scope.loggedIn = false;
scope.logout = function() {
$http.get('backend/logout.php').success(function(data) {
scope.loggedIn = false;
scope.$broadcast('event:doCheckLogin');
}).error(function(data) {
scope.$broadcast('event:doCheckLogin');
});
};
scope.$on('event:loginRequired', function() {
//Only redirect if we aren't on restricted pages
if ($location.path() == "/signup" ||
$location.path() == "/login" ||
$location.path() == "/contact" ||
$location.path() == "/about")
return;
//go to the login page
$location.path('/login').replace();
});
/**
* On 'event:loginConfirmed', return to the page.
*/
scope.$on('event:loginConfirmed', function() {
//*********************
//THIS IS WHERE I SET loggedIN
//*********************
scope.loggedIn = true;
console.log("Login confirmed!");
$location.path('/lobby').replace();
});
/**
* On 'logoutRequest' invoke logout on the server and broadcast 'event:loginRequired'.
*/
scope.$on('event:logoutRequest', function() {
scope.logout();
});
scope.$on("$locationChangeSuccess", function(event) {
//event.preventDefault();
ping();
});
scope.$on('event:doCheckLogin', function() {
ping();
});
/**
* Ping server to figure out if user is already logged in.
*/
function ping() {
$http.get('backend/checksession.php').success(function() {
scope.$broadcast('event:loginConfirmed');
}); //If it fails the interceptor will automatically redirect you.
}
//Finally check the logged in state on every load
ping();
}
]);
答案 0 :(得分:1)
你们是对的。我使用异步调用将loggedIn设置为true,所以这完全是时间问题。
欢迎来到异性恋世界亲爱的我。
$watch
- ing loggedIn
解决了这个问题。
appControllers.controller("NavController", function($rootScope, $scope) {
$scope.showHomeMenu = true;
$scope.showGameMenu = false;
$scope.currentHome = '/login';
//ADDED
$rootScope.$watch('loggedIn', function(){
console.log($rootScope.loggedIn);
if($rootScope.loggedIn === true){
$scope.showHomeMenu = false;
$scope.showGameMenu = true;
$scope.currentHome = '/lobby';
}
else {
$scope.showHomeMenu = true;
$scope.showGameMenu = false;
$scope.currentHome = '/login';
}});
});
此外,我更改了在我的代码中将loggedIn设置为false的位置,以提高性能并在注销时消除可见延迟。现在一切都很快。