尝试使用 Angular rootScope 跨控制器持久保存数据,但总是未定义
Trying to persist data across controllers using Angular rootScope, but always getting undefined
我有一个管理员登录页面。当用户以管理员身份成功登录后,我想在用户访问的所有页面顶部显示:
<!-- nav bar -->
<div>
<span ng-show="$root.isAdmin">(ADMIN)</span>
</div>
我尝试使用 $rootScope
来完成此操作,但我一直收到 undefined
:
// controller for logging in
app.controller('AdminLoginCtrl', [ '$rootScope', '$scope', 'stateParams', 'loginService', function($rootScope, $scope, $stateParams, loginService) {
loginService.success(function() {
$rootScope.isAdmin = true;
console.log($rootScope.isAdmin); // returns true
$location.path("/login_success");
});
}]);
// some other controller AFTER user is logged in as admin
app.controller('BlahCtrl', ['$rootScope', '$scope', function($rootScope, $scope) {
console.log($rootScope.isAdmin); // returns 'undefined'
});
还有其他一些类似的主题,但不适用于我:
(我没有注射问题):
$rootscope value undefined in Controller
(我的另一个控制器肯定在登录后被调用,所以应该设置 $rootScope.isAdmin
):
AngularJS - Cannot access RootScope
(我没有订购问题):
Angular $rootScope.$on Undefined
其他解决方案可能是不使用$rootScope
,只使用服务来保存共享数据.但是,如果我有 10 个以上的控制器,是否可以在每个控制器中执行此操作:
app.controller('...', ['$scope', 'checkAdminService', function($scope, checkAdminService) {
$scope.isAdmin = checkAdminService.getIsAdmin()
}]);
然后:
<span ng-show="isAdmin">(ADMIN)</span>
这是可以接受还是更麻烦?为了完整起见,为什么 $rootScope
解决方案根本不起作用?
使用 $rootScope 确实是一种不好的做法。最好的解决方案是您自己建议创建一个服务来存储您想要在不同控制器之间共享的信息。在多个位置调用这个方法是没有问题的...
为什么不为页面的顶部定义一个单独的控制器,它将是唯一一个验证用户是否为管理员的控制器?页面的其他部分可以由不同的控制器控制。
这个例子将说明如何使用多个控制器,当然这也可以通过路由器来实现。
如果您将正在传递的 $rootScope
替换为可以在启动时注册并根据需要传递的特殊用途 angular value
会怎样?
http://plnkr.co/edit/r6kdouh0BbnYA4DmEcEM?p=preview
angular
.module('app')
.value('userProfile', userProfile);
function userProfile() {
var userProfile = {
isAdmin: false
};
return userProfile;
}
/////////////////
angular
.module('app')
.run(run);
run.$inject = ['userProfile', 'userAuthService'];
function run(userProfile, userAuthService) {
userAuthService.isUserAdmin().then(function(result) { userProfile.isAdmin = result; });
}
angular.module('yourmodule', [])
.run(['$rootScope', function($rootScope) {
$rootScope.isAdmin = true;
])
我有一个管理员登录页面。当用户以管理员身份成功登录后,我想在用户访问的所有页面顶部显示:
<!-- nav bar -->
<div>
<span ng-show="$root.isAdmin">(ADMIN)</span>
</div>
我尝试使用 $rootScope
来完成此操作,但我一直收到 undefined
:
// controller for logging in
app.controller('AdminLoginCtrl', [ '$rootScope', '$scope', 'stateParams', 'loginService', function($rootScope, $scope, $stateParams, loginService) {
loginService.success(function() {
$rootScope.isAdmin = true;
console.log($rootScope.isAdmin); // returns true
$location.path("/login_success");
});
}]);
// some other controller AFTER user is logged in as admin
app.controller('BlahCtrl', ['$rootScope', '$scope', function($rootScope, $scope) {
console.log($rootScope.isAdmin); // returns 'undefined'
});
还有其他一些类似的主题,但不适用于我:
(我没有注射问题):
$rootscope value undefined in Controller
(我的另一个控制器肯定在登录后被调用,所以应该设置 $rootScope.isAdmin
):
AngularJS - Cannot access RootScope
(我没有订购问题):
Angular $rootScope.$on Undefined
其他解决方案可能是不使用$rootScope
,只使用服务来保存共享数据.但是,如果我有 10 个以上的控制器,是否可以在每个控制器中执行此操作:
app.controller('...', ['$scope', 'checkAdminService', function($scope, checkAdminService) {
$scope.isAdmin = checkAdminService.getIsAdmin()
}]);
然后:
<span ng-show="isAdmin">(ADMIN)</span>
这是可以接受还是更麻烦?为了完整起见,为什么 $rootScope
解决方案根本不起作用?
使用 $rootScope 确实是一种不好的做法。最好的解决方案是您自己建议创建一个服务来存储您想要在不同控制器之间共享的信息。在多个位置调用这个方法是没有问题的...
为什么不为页面的顶部定义一个单独的控制器,它将是唯一一个验证用户是否为管理员的控制器?页面的其他部分可以由不同的控制器控制。
这个例子将说明如何使用多个控制器,当然这也可以通过路由器来实现。
如果您将正在传递的 $rootScope
替换为可以在启动时注册并根据需要传递的特殊用途 angular value
会怎样?
http://plnkr.co/edit/r6kdouh0BbnYA4DmEcEM?p=preview
angular
.module('app')
.value('userProfile', userProfile);
function userProfile() {
var userProfile = {
isAdmin: false
};
return userProfile;
}
/////////////////
angular
.module('app')
.run(run);
run.$inject = ['userProfile', 'userAuthService'];
function run(userProfile, userAuthService) {
userAuthService.isUserAdmin().then(function(result) { userProfile.isAdmin = result; });
}
angular.module('yourmodule', [])
.run(['$rootScope', function($rootScope) {
$rootScope.isAdmin = true;
])