I'm a newbie to angularjs.
My problem is that I have a User Controller for handling Login and Logout. I have also another controller to load a header menu for my site.
If the user logs in to the site my isAuthenticated variable is set to true. If the variable is set to true the header should be change but, so I think the controller must be reloaded to change the header view.
Here the code of my HeaderController:
myapp.controller('HeaderController', ['$scope', '$location', '$window', 'AuthenticationService',
function HeaderController($scope, $location, $window, AuthenticationService) {
$scope.isAuthenticated = AuthenticationService.isAuthenticated;
if (AuthenticationService.isAuthenticated) {
$scope.user.vorname = $window.sessionStorage.user.vorname;
}
}
]);
Here's the code of my HeaderDirective:
myapp.directive('appHeader', function() {
return {
restrict: 'E',
link: function(scope, element, attrs) {
if (attrs.isauthenticated == 'false') {
scope.headerUrl = 'views/header/index.html';
} else {
scope.headerUrl = 'views/header/isAuthenticated.html';
}
},
template: '<div ng-include="headerUrl"></div>'
}
});
My index.html:
<div ng-controller="HeaderController">
<app-header isauthenticated="{{isAuthenticated}}"></app-header>
</div>
How can I reload the controller if the user logs in to the page?
PS: Please excuse my poor pronunciation.
There's no need to reload your controller. Angular is smart enough to change the template when the $scope.isAuthenticated
state changes.
One problem I see in your code is that once the $scope.isAuthenticated
is defined it does not change anymore. I suppose you are setting AuthenticationService.isAuthenticated = true
when user logs in but that change aren't being propagated to the $scope.isAuthenticated
property because in JavaScript scalar values are copied by value instead of by reference.
There are many approaches, such as changing the AuthenticationService.isAuthenticated
property from a boolean to a function:
angular.module('auth', [])
.factory('AuthenticationService', function () {
// private state
var isAuthenticated = false;
// getter and setter
var auth = function (state) {
if (typeof state !== 'undefined') { isAuthenticated = state; }
return isAuthenticated;
};
// expose getter-setter
return { isAuthenticated: auth };
});
Then assign that function to the $scope:
$scope.isAuthenticated = AuthenticationService.isAuthenticated;
Then use the function in your template (don't forget the parens)
<app-header isauthenticated="{{ isAuthenticated() }}"></app-header>
Edit:
While writing a plunk to show you a working example I have realized that the link function of the directive is not called more than once, so as exposed in this stackoverflow thread I just modified the directive to observe changes in the isauthenticated
attribute:
angular.module('directives', [])
.directive('appHeader', function() {
var bool = {
'true': true,
'false': false
};
return {
restrict: 'E',
link: function (scope, element, attrs) {
attrs.$observe('isauthenticated', function (newValue, oldValue) {
if (bool[newValue]) { scope.headerUrl = 'authenticated.html'; }
else { scope.headerUrl = 'not-authenticated.html'; }
});
},
template: '<div ng-include="headerUrl"></div>'
}
});
And here is the working example
Add this piece of code after the user is authenticated:
// To refresh the page
$timeout(function () {
// 0 ms delay to reload the page.
$route.reload();
}, 0);
Don't forget to include $timeout
and $route
in your controller.
myapp.controller('HeaderController', ['$scope', '$location', '$window', 'AuthenticationService', '$timeout', '$route',
function HeaderController($scope, $location, $window, AuthenticationService, $timeout, $route)