Reputation: 35
I am hiding and showing nav bar elements based on if the user is logged in or out.
In the main controller:
$scope.FBlogin = function(){
FB.login(function(response) {
if (response.authResponse) {
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function(response) {
console.log('Good to see you, ' + response.name + '.');
$cookies.put('userObj', response);
var accessToken = FB.getAuthResponse().accessToken;
console.log(accessToken);
authFact.setAccessToken(accessToken);
console.log(response);
$scope.out=true;
$scope.in = false;
$scope.feed = true;
$location.path("/myFeed");
$scope.$apply();
});
} else {
console.log('User cancelled login or did not fully authorize.');
}
});
};
$scope.FBlogout = function(){
$scope.out = false;
$scope.in = true;
$scope.feed = false;
$cookies.remove("userObj");
$cookies.remove('accessToken');
$location.path("/");
$scope.$apply();
};
}]);
It works here when the login function is called from the list item. The login link disappears and the logout link shows.
Navigation directive (part of main controller)
<li ng-click="FBlogin()" ng-if="in"><a href="#login">Login</a></li>
<li ng-if="feed"><a href="#myFeed">My Feed</a></li>
<li id="logout" ng-click="FBlogout()" ng-if="out"><a>Logout</a></li>
angular.module('dsnApp')
.directive('navApp', function(){
return{
templateUrl: 'templates/nav.html',
controller:'mainController',
replace: 'true'
}
});
However when this button calls the login function the login button does not disappear and the logout does not show.
Login directive (part of main controller)
<div class="fbLogin" ng-controller="mainController">
<h1 style="display: inline-block">Login with <span id="facebook">facebook</span></h1><br>
<button ng-click="FBlogin()">Login</button>
</div>
app.config(function($routeProvider) {
$routeProvider
// route for the home page
.when('/', {
templateUrl : 'templates/home.html',
controller : 'mainController'
})
// route for the about page
.when('/explore', {
templateUrl : 'templates/explore.html',
controller : 'exploreController'
})
// route for the service page
.when('/login', {
templateUrl : 'templates/login.html',
controller : 'mainController'
})
// route for the about page
.when('/myFeed', {
templateUrl : 'templates/myFeed.html',
controller : 'feedController',
authenticated : true
})
.otherwise('/', {
templateUrl : 'templates/home.html',
controller : 'mainController'
});
});
Does this have to do with scope at all?
Upvotes: 2
Views: 331
Reputation: 48968
Does this have to do with scope at all?
Yes, it very much has to do with scope.
<body ng-controller="mainController">
<div>
<ul class="nav">
<li id="home"><h1><a href="#/">Do Something Nice</a></h1></li>
<li><a href="#explore">Explore</a></li>
<li><a href="#login">Login</a></li>
<li><a href="#myFeed">My Feed</a></li>
<li id="logout" ng-click="FBlogout()"> <a>Logout</a></li>
</ul>
</div>
<!-- this is where content will be injected -->
<div id="main">
<!-- angular templating -->
<!-- this is where content will be injected -->
<div ng-view></div>
The body of the app has an ng-controller
directive which creates a child scope and injects the mainController
.
The ng-view
directive is creating another child scope and the route is instantiating another mainController
on that scope.
In addition, the ng-if
directive is creating yet another child scope.
To make things worse, the custom dsn-app
directive is instantiating yet another mainController
.
To learn about scopes, I recommend reading:
Upvotes: 0
Reputation: 6060
It clearly have something to do with your scope
. The $scope.in
must have the same scope with both $scope.FBLogin()
and $scope.FBlogout()
.
Since you said that you're using Navigation directive, I'm guessing that you have:
Although they're all have the same $scope
as their dependency injector, their content aren't the same.
To achieve what do you want to do, you must share a variable that controls the navbar's visibility across your app (controllers and directives). Below is how you can do it, with a working example below that
// angular app.js
var app = angular.module('app', []);
// main controller
app.controller('MainController', function($scope, navbarState) {
$scope.hide = function(){
navbarState.hideNavbar(); // executes this when logout
}
});
// navbar directive which use navbarState service
// to show navbar, we use `ng-if` (see template)
app.directive('navbarDirective', function(){
return {
restrict: 'EA',
template: "<div ng-if=\"navbarState.currentState == 'show'\"></div>",
controller: function ($scope, navbarState) {
$scope.navbarState = navbarState;
}
}
});
// navbarState is a service that is shared across
// directives and controllers in your app.
// this service holds a value (currentState) which indicates
// navbar when to show or hide
app.service('navbarState', function($window) {
this.currentState = "show";
this.showNavbar = function(){
this.currentState = "show";
}
this.hideNavbar = function(){
this.currentState = "hide";
}
});
Please see this plunkr example for detailed answer: https://plnkr.co/edit/LCS4NxJwcbfeVAXgLKJ8?p=preview
Upvotes: 2