AngularJS - 如果用户登录,则显示/隐藏导航项
AngularJS - show/hide nav items if user is logged in
我有一个单页的AngularJS应用程序,通过Mongoose使用Express,node.js和MongoDB。使用护照进行用户管理/身份验证。
我希望导航栏项根据用户是否登录而更改。我无法弄清楚如何实现它。
我发现用户是否通过http
请求登录:
服务器.js
app.get('/checklogin',function(req,res){
if (req.user)
res.send(true);
else
res.send(false);
在前端,我有一个使用 Angular 的$http
服务调用它的NavController
:
导航控制器.js
angular.module('NavCtrl',[]).controller('NavController',function($scope,$http) {
$scope.loggedIn = false;
$scope.isLoggedIn = function() {
$http.get('/checklogin')
.success(function(data) {
console.log(data);
if (data === true)
$scope.loggedIn = true;
else
$scope.loggedIn = false;
})
.error(function(data) {
console.log('error: ' + data);
});
};
};
在我的导航中,我使用ng-show
和ng-hide
来确定哪些选择应该可见。当用户单击导航项时,我还触发了isLoggedIn()
功能,检查用户在每次单击期间是否登录。
索引.html
<nav class="navbar navbar-inverse" role="navigation">
<div class="navbar-header">
<a class="navbar-brand" href="/">Home</a>
</div>
<ul class="nav navbar-nav">
<li ng-hide="loggedIn" ng-click="isLoggedIn()">
<a href="/login">Login</a>
</li>
<li ng-hide="loggedIn" ng-click="isLoggedIn()">
<a href="/signup">Sign up</a>
</li>
<li ng-show="loggedIn" ng-click="logOut(); isLoggedIn()">
<a href="#">Log out</a>
</li>
</ul>
</nav>
问题
在我的应用程序中,用户还可以在导航控制器范围之外登录/注销的其他位置。例如,登录页面上有一个登录按钮,对应于登录控制器。我想有一种更好的方法可以在我的整个应用程序中实现这一点。
如何"观察"后端是否true
req.user
并让我的导航项做出相应的响应?
您可以使用$rootScope
在整个应用中共享信息:
.controller('NavController',function($scope,$http, $rootScope) {
$scope.isLoggedIn = function() {
$http.get('/checklogin')
.success(function(data) {
console.log(data);
$rootScope.loggedIn = data;
})
.error(function(data) {
console.log('error: ' + data);
});
};
};
现在,你可以通过访问 $rootScope.loggedIn
来更改应用中其他位置的 loggedIn
的值,方法与上面的代码中的相同方式相同。
话虽如此,您应该将相关代码抽象为服务和指令。这将允许您有一个中心位置来处理、登录、注销和$rootScope.loggedIn
的状态。如果您发布其余的相关代码,我可以帮助您提供更具体的答案
您可以在用户成功登录时广播该事件。如果用户已登录,则无需继续轮询您的服务器,您可以在内存中保留一个变量,告诉您是否有有效的会话。您可以使用在服务器端设置的基于令牌的身份验证:
services.factory('UserService', ['$resource',
function($resource){
// represents guest user - not logged
var user = {
firstName : 'guest',
lastName : 'user',
preferredCurrency : "USD",
shoppingCart : {
totalItems : 0,
total : 0
},
};
var resource = function() {
return $resource('/myapp/rest/user/:id',
{ id: "@id"}
)};
return {
getResource: function() {
return resource;
},
getCurrentUser: function() {
return user;
},
setCurrentUser: function(userObj) {
user = userObj;
},
loadUser: function(id) {
user = resource.get(id);
}
}
}]);
services.factory('AuthService', ['$resource', '$rootScope', '$http', '$location', 'AuthenticationService',
function ($resource, $rootScope, $http, $location, AuthenticationService) {
var authFactory = {
authData: undefined
};
authFactory.getAuthData = function () {
return this.authData;
};
authFactory.setAuthData = function (authData) {
this.authData = {
authId: authData.authId,
authToken: authData.authToken,
authPermission: authData.authPermission
};
// broadcast the event to all interested listeners
$rootScope.$broadcast('authChanged');
};
authFactory.isAuthenticated = function () {
return !angular.isUndefined(this.getAuthData());
};
authFactory.login = function (user, functionObj) {
return AuthenticationService.login(user, functionObj);
};
return authFactory;
}]);
services.factory('AuthenticationService', ['$resource',
function($resource){
return $resource('/myapp/rest/auth/',
{},
{
'login': { method: "POST" }
}
);
}]);
services.factory('authHttpRequestInterceptor', ['$injector',
function ($injector) {
var authHttpRequestInterceptor = {
request: function ($request) {
var authFactory = $injector.get('AuthService');
if (authFactory.isAuthenticated()) {
$request.headers['auth-id'] = authFactory.getAuthData().authId;
$request.headers['auth-token'] = authFactory.getAuthData().authToken;
}
return $request;
}
};
return authHttpRequestInterceptor;
}]);
控制器:
controllers.controller('LoginCtrl', ['$scope', '$rootScope', 'AuthService', 'UserService',
function LoginCtrl($scope, $rootScope, AuthService, UserService) {
$scope.login = function () {
AuthService.login($scope.userInfo, function (data) {
AuthService.setAuthData(data);
// set user info on user service to reflect on all UI components
UserService.setCurrentUser(data.user);
$location.path('/home/');
});
};
$scope.isLoggedIn = function () {
return AuthService.isAuthenticated();
}
$scope.user = UserService.getCurrentUser();
}])
您可以使用一些模板库(如 EJS)在索引中添加用户的会话数据.html。
只需添加 ejs 中间件:
var ejs = require('ejs');
// Register ejs as .html.
app.engine('.html', ejs.__express);
然后,在返回索引时.html将会话数据呈现到响应中。
res.render( "/index.html", {
session : {
user_data : JSON.stringify(req.user)
}
});
您现在可以访问索引.html中的数据,现在您需要将其加载到 Angular 应用程序中。我使用了预加载资源示例,但您可以使用自己的方式。
如果您希望登录名保留在当前会话之外,也可以使用 $localStorage。我发现这个库对这些类型的情况非常有帮助。(https://github.com/grevory/angular-local-storage)
- 在jquery中为显示/隐藏设置cookie
- PHP Javascript显示/隐藏按钮不工作
- 打开/关闭按钮以显示/隐藏内容
- 显示隐藏复选框
- 在bootstrap中显示隐藏特定的li
- JQuery上下文菜单显示/隐藏问题
- JQuery在单击时停止显示/隐藏
- HTML5在提交并显示所需标签后显示隐藏的表单元素
- 使用 jQuery 切换显示/隐藏
- 显示/隐藏有关模型更改的指令内容
- Bootstrap在页面加载缓慢时会立即显示隐藏的模式对话框
- 根据特定条件使用ng显示/ng隐藏来显示/隐藏元素
- 显示/隐藏不起作用
- 使用ng-hide根据条件显示/隐藏按钮
- 仅在第一个结果中显示/隐藏MySQL结果函数
- 显示/隐藏http://ftp链接
- 在显示/隐藏中单击时删除的文本
- 是否可以在不重新渲染的情况下显示/隐藏父对象中的元素
- 将页面内容向左移动时显示/隐藏右侧面板
- 显示/隐藏将不会加载