所以我遇到了这个问题,我正在使用ngView,我有一个静态的导航栏,如下所示:
<div ng-include="'views/nav.html'" ng-controller="NavCtrl"></div>
<div class="container-fluid" ng-view=""></div>
此nav.html(导航栏)显示一组特定功能(登录,注册),如果用户已注销(使用ng-show)和其他菜单选项(如果用户已登录)。由于重使用当前用户,我把这些信息放在$ rootScope中,如下所示:$rootScope.currentUser
- 返回用户对象,$rootScope.signedIn
- 返回布尔值。
基本上,我想延迟加载导航栏,直到加载$rootScope.signedIn
为真或假,$rootScope.currentUser
是对象或未定义。
我已经尝试过在app.config路由中创建promises,但我不确定如何将promise返回到永久视图状态。
感谢任何帮助。
修改:
这是我广播登录的服务。只要用户通过身份验证/登录或注销时,就会触发此消息:
var authClient = new FirebaseSimpleLogin(refDownload, function(error, user) {
if (error) {
incorrectLogin(error.code);
}
if (user) {
// user authenticated
$rootScope.$broadcast('login');
correctLogin(user.id);
} else {
// user is logged out
$rootScope.$broadcast('logout');
}
});
此服务按以下方式注入NavCtrl控制器:
$scope.isHidden = true;
$scope.$on('login', function() {
console.log('login broadcast');
$scope.isHidden = false;
});
$scope.$on('logout', function() {
console.log('broadcast logout');
$scope.isHidden = true;
});
此控制器的模板是nav.html,如下所示:
<div class="col-xs-4 centered" id="nav-hover" ng-show="isHidden">
<ul class="nav navbar-nav">
<li id="nav-login"><a ng-href="#/login"><span class="glyphicon glyphicon-log-in"> Login</span></a></li>
</ul>
</div>
<div class="col-xs-4 centered" id="nav-hover" ng-show="isHidden">
<ul class="nav navbar-nav">
<li id="nav-login"><a ng-href="#/register"><span class="glyphicon glyphicon-edit"> Register</span></a></li>
</ul>
</div>
<div class="col-xs-2 centered" id="nav-hover">
<ul class="nav navbar-nav" ng-hide="isHidden">
<li ng-class="{{ chatCat.active }}"><a ng-href="{{ chatCat.url }}"><span class="{{ chatCat.icon }}"></span></a></li>
</ul>
</div>
同样,此视图绑定到NavCtrl。当用户登录时,我按如下方式使用AuthCtrl:
$scope.login = function() {
if ($scope.user !== undefined) {
Auth.login($scope.user);
$location.path('/dexter');
} else {
console.log('nothing entered');
}
};
当我尝试登录时,导航视图不会使用新值更新,尽管广播是通过“登录”从服务中触发的。
验证服务:
'use strict';
app.factory('Auth',
function($rootScope, $location, $firebase, $firebaseSimpleLogin, firebaseUrl) {
var refDownload = new Firebase(firebaseUrl + 'housemates');
var sync = $firebase(refDownload);
var ref = sync.$asObject();
var authClient = new FirebaseSimpleLogin(refDownload, function(error, user) {
if (error) {
incorrectLogin(error.code);
}
if (user) {
// 1
// user authenticated
correctLogin(user.id);
} else {
// user is logged out
// $rootScope.signedIn = false;
}
});
var Auth = {
housemates: ref,
changeColor: function(color) {
var id = $rootScope.currentUser.id.toString();
refDownload.child(id).update({ color: color });
$rootScope.currentUser.color = color;
},
create: function(authUser, usr) {
refDownload.child(authUser.id).set({
initials: usr.initials,
email: authUser.email,
password: usr.password,
color: 'Blue',
id: authUser.id,
uid: authUser.uid,
rememberMe: true,
});
},
// 3
findById: function(id) {
refDownload.on('value', function(snapshot) {
var userObject = snapshot.val();
// 4 - sets currentUser
//$rootScope.currentUser = userObject[id];
var currentUser = userObject[id];
Auth.setUser(currentUser);
// $rootScope.signedIn = true;
}, function (error) {
console.log(error);
});
},
login: function(user) {
authClient.login('password', {
email: user.email,
password: user.password,
rememberMe: true
});
},
logout: function() {
delete $rootScope.currentUser;
delete $rootScope.signedIn;
delete $rootScope.error;
return authClient.logout();
},
register: function(user) {
var userSimple = user;
authClient.createUser(user.email, user.password, function(error, user) {
if(!error) {
var userComplex = user;
Auth.login(userSimple);
Auth.create(userComplex, userSimple);
return user;
} else {
console.log(error);
}
});
},
setUser: function(aUser) {
console.log('setuser ran');
$rootScope.currentUser = aUser;
console.log('setUser: ' + $rootScope.currentUser);
},
isLoggedIn: function() {
console.log($rootScope.currentUser);
return ($rootScope.currentUser) ? $rootScope.currentUser : false;
},
};
// 2
function correctLogin(id) {
Auth.findById(id);
}
function incorrectLogin(error) {
alert(error);
$rootScope.error = error;
}
return Auth;
});
答案 0 :(得分:6)
在菜单上有一点$ rootScope。$ broadcast和ng-hide,这很容易实现。见plunker
html:
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js@1.2.x" src="https://code.angularjs.org/1.2.25/angular.js" data-semver="1.2.25"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<div ng-include="'nav.html'" ng-controller="NavCtrl" ng-hide="isHidden"></div>
<button class="btn" ng-click="login()">Login</button>
<button class="btn" ng-click="logout()">Logout</button>
</body>
</html>
javascript:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, $rootScope) {
$scope.login = function() {
$rootScope.$broadcast("login");
}
$scope.logout = function() {
$rootScope.$broadcast("logout");
}
});
app.controller('NavCtrl', function($scope) {
$scope.isHidden = true;
$scope.$on('login', function() {
console.log("logged in");
$scope.isHidden = false;
});
$scope.$on('logout', function() {
console.log("logged out");
$scope.isHidden = true;
});
});
答案 1 :(得分:1)
好的,如果我建议的方式不适合你,这是第二种可能的解决方案(plunker)
基本思想是拥有一个服务(在本例中为工厂),您在其中设置登录的用户名,然后在导航控制器中使用$ watch来监视服务中身份验证状态的更改。代码:
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js@1.2.x" src="https://code.angularjs.org/1.2.25/angular.js" data-semver="1.2.25"></script>
<script src="app.js"></script>
<script src="Auth.js"></script>
</head>
<body ng-controller="MainCtrl">
<div ng-include="'nav.html'" ng-controller="NavCtrl" ng-hide="isHidden"></div>
<button class="btn" ng-click="login()">Login</button>
<button class="btn" ng-click="logout()">Logout</button>
</body>
</html>
javascript:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, $rootScope, Auth) {
$scope.login = function() {
var user = "iris"
Auth.setUser(user);
}
$scope.logout = function() {
Auth.setUser(null);
}
});
app.controller('NavCtrl', function($scope, Auth) {
$scope.isHidden = true;
$scope.$watch(Auth.isLoggedIn, function (value, oldValue) {
console.log("authentication changed");
if(!value && oldValue) {
console.log("logged out");
$scope.isHidden = true;
}
if(value) {
console.log("logged in");
$scope.isHidden = false;
}
}, true);
});
和服务:
app.factory('Auth', function() {
var user;
return {
setUser: function(aUser) {
user = aUser;
},
isLoggedIn: function() {
console.log(user);
return (user) ? user : false;
}
}
})
答案 2 :(得分:0)
@zszep $广播答案解决了这个问题,一个警告。必须在NavCtrl中的每个$ scope.isHidden命令后面添加$scope.$apply()
。这会强制页面刷新排序并更新导航视图。