我真的只是在学习Angular,我正在尝试创建一个基于身份验证限制内容访问的应用程序。我有认证部分工作(也使用Laravel PHP框架),但我有一个问题“重新加载”基于身份验证状态的某些内容,即成功的身份验证后。
最初,我要做的是在用户登录后更新主导航菜单。我确信有更好的方法,但到目前为止我所拥有的是从具有不同导航元素的服务器返回的视图取决于用户是否登录,然后将其加载到具有ng-include的元素中。
可以选择登录,将登录表单加载到ng-view中。用户登录后,我想用服务器的视图刷新ng-include。
成功登录后,有没有办法在ng-include中重新加载该模板?
如果这是错误的方法,请随时推荐更好的解决方法。当然,这在jQuery中很容易做到,但我更喜欢用Angular方式做事。
以下是我目前的一些代码:
的index.html:
<div class="container" ng-controller="appController">
<div id="nav" ng-include src="menuUrl()"></div>
<div class="row">
<div class="span3" ng-include src="'partials/brands.html'" ng-controller="brandController"></div>
<div class="span9" ng-view></div>
</div>
</div>
一些控制器:
.controller('appController', function($scope){
$scope.loggedIn = false;
$scope.menuUrl = function() {
return "partials/nav.html";
};
})
.controller('loginController',function($scope, $sanitize, $location, Authenticate, Flash){
$scope.login = function(){
Authenticate.save({
'email': $sanitize($scope.email),
'password': $sanitize($scope.password)
},function() {
$location.path('/products')
Flash.clear()
sessionStorage.authenticated = true;
},function(response){
Flash.show(response.flash)
})
}
})
.controller('logoutController',function($scope, $location, Authenticate, Flash){
$scope.logout = function (){
Authenticate.get({},function(response){
delete sessionStorage.authenticated
Flash.show(response.flash)
$location.path('/login')
})
}
})
服务:
.factory('Authenticate', function($resource){
return $resource("/service/authenticate/")
})
.factory('Flash', function($rootScope){
return {
show: function(message){
$rootScope.flash = message
},
clear: function(){
$rootScope.flash = ""
}
}
})
App:
.config(['$routeProvider',function($routeProvider){
$routeProvider.when('/', {
templateUrl: 'partials/home.html',
controller: 'homeController'
})
$routeProvider.when('/login', {
templateUrl: 'partials/login.html',
controller: 'loginController'
})
$routeProvider.when('/logout', {
templateUrl: 'partials/logout.html',
controller: 'logoutController'
})
$routeProvider.otherwise({redirectTo :'/'})
}])
.config(function($httpProvider){
var interceptor = function($rootScope,$location,$q,Flash){
var success = function(response){
return response
}
var error = function(response){
if (response.status == 401){
delete sessionStorage.authenticated
$location.path('/')
Flash.show(response.data.flash)
}
return $q.reject(response)
}
return function(promise){
return promise.then(success, error)
}
}
$httpProvider.responseInterceptors.push(interceptor)
})
.run(function($http,CSRF_TOKEN){
$http.defaults.headers.common['csrf_token'] = CSRF_TOKEN;
})
Laravel观点:
<ul class="nav nav-tabs">
<li><a href="#/">Home...</a></li>
@if(!Auth::check())
<li><a href="#/login">Log-in</a></li>
@else
<li><a href="#/logout">Log-out</a></li>
@endif
<li><input name="search" id="search" type="search" placeholder="Search products..." />
</ul>
答案 0 :(得分:12)
当使用广播方法
在rootcope上成功登录用户时,您可以开始提升事件$rootScope.$broadcast('userLoggedIn',{user:user});
在appController
上,您可以订阅偶数
$scope.$on("userLoggedIn",function(event,args) {
$scope.menuUrl=null;
$scope.menuUrl="partials/nav.html";
});
这也意味着将menuUrl更改为控制器和html绑定中的属性。
Alos,如果您可以为登录和匿名用户定义多个服务器视图,那么您可以在用户登录时翻转视图。
答案 1 :(得分:9)
@Chandermani的答案几乎接近,事实上,你可以添加一些随机参数来强制刷新,就像这样:
app.controller('appController', function($scope){
var getMenu = function(){
var random = Math.random();
return "partials/nav.html?r=" + random;
}
$scope.menuUrl = getMenu();
$scope.$on('userLoggedIn', function(){
$scope.menuUrl = getMenu();
})
})