2015-04-06 77 views
0

我正在將接線認證工作到我的應用程序中。如果用戶已登錄,我想在導航欄中顯示註銷按鈕。ng-show不更新導航欄中的註銷按鈕

我在我的控制器中設置$ scope.authenticated,但註銷按鈕不會一直顯示出來。 。

我讀過,我需要使用$ $的範圍適用於告訴角變量被更新,但是當我這樣做,我得到這個錯誤:https://docs.angularjs.org/error/ $ rootScope/inprog P0 = $消化

我已經工作了plunker一個演示應用程序顯示我的問題:http://plnkr.co/edit/gCSGIC0gXbfuIjVgp01f?p=preview

App.js

'use strict'; 
 

 
var app = angular.module('salesmanApp', ['ngStorage', 'ngRoute']); 
 

 
app.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) { 
 
    $routeProvider.when('/login', { 
 
     templateUrl: 'login.html', 
 
     controller: 'loginController', 
 
     login: true 
 
    }); 
 
    $routeProvider.when('/home', { 
 
     templateUrl: 'home.html', 
 
     controller: 'homeController' 
 
    }); 
 

 
    $routeProvider.otherwise({ 
 
     redirectTo: '/home' 
 
    }); 
 
}]); 
 

 

 
app.run(['$location', '$rootScope', 'TokenStorage', function($location, $rootScope, TokenStorage) { 
 

 
\t if (TokenStorage.retrieve() != null) { 
 
\t \t $rootScope.authenticated = true; 
 
\t } 
 
    $rootScope.$on("$routeChangeStart", function(event, next, current) { 
 
     if (!$rootScope.authenticated && next && !next.login) { 
 
      event.preventDefault(); 
 
      $rootScope.$evalAsync(function() { 
 
       $location.path('/login'); 
 
      }); 
 
     } 
 
    }); 
 
}]); 
 

 

 
app.config(function($httpProvider) { 
 
    $httpProvider.interceptors.push('TokenAuthInterceptor'); 
 
});

Controllers.js

var app = angular.module('salesmanApp'); 
 

 
// create the controller and inject Angular's $scope 
 
app.controller('mainController', ['$scope', '$location', '$rootScope', 'AuthService', '$timeout', function($scope, $location, $rootScope, AuthService, $timeout) { 
 
    // create a message to display in our view 
 
    $scope.logout = function() { 
 
    \t 
 
    \t AuthService.logout(function() { 
 

 
    \t \t $scope.authenticated = false; 
 
      $rootScope.authenticated = false; 
 
      $location.path('/login'); 
 

 
    \t }); 
 

 
    }; 
 
}]); 
 

 
app.controller('loginController', ['$scope', '$location', '$rootScope', 'TokenStorage', 'AuthService', '$timeout', function($scope, $location, $rootScope, TokenStorage, AuthService, $timeout) { 
 
    $scope.authenticated = false; 
 

 
    $scope.login = function() { 
 
    
 
    \t var formData = { 
 
    \t \t \t username: $scope.username, 
 
    \t \t \t password: $scope.password 
 
     } 
 
    \t 
 
    \t AuthService.login(formData, function(token) { 
 

 
    \t \t  $scope.authenticated = true; 
 
      $rootScope.authenticated = true; 
 
\t \t 
 
      TokenStorage.store(token); 
 
      $location.path('/home'); 
 

 
      
 
    \t }, function() { 
 

 
    \t \t \t $scope.authenticated = false; 
 
      $rootScope.authenticated = false; 
 
      $scope.error = "Invalid Username or Password" 
 
      TokenStorage.clear(); 
 
      
 
    \t }); 
 

 

 
    }; 
 
}]); 
 

 
app.controller('homeController', ['$scope', '$http', '$location', 'UserService', function($scope, $http, $location, UserService) { 
 

 

 

 
}]);

Services.js

var app = angular.module('salesmanApp'); 
 

 
app.factory('UserService', ['$http', '$q', function($http, $q) { 
 
    
 
\t return { 
 
\t \t getCurrentUserName : function() { 
 
\t  \t return $http.get('/api/users/current'); 
 
\t \t } 
 
\t }; 
 
}]); 
 

 
app.factory('TokenStorage', ['$localStorage', function($localStorage) { 
 
    var storageKey = 'auth_token'; 
 
    return { 
 
     store: function(token) { 
 
      return $localStorage.auth_token = token; 
 
     }, 
 
     retrieve: function() { 
 
      return $localStorage.auth_token; 
 
     }, 
 
     clear: function() { 
 
      delete $localStorage.auth_token; 
 
     } 
 
    }; 
 
}]); 
 

 
app.factory('TokenAuthInterceptor', ['$q', 'TokenStorage', function($q, TokenStorage) { 
 
    return { 
 
     request: function(config) { 
 
      var authToken = TokenStorage.retrieve(); 
 
      if (authToken) { 
 
       config.headers['X-AUTH-TOKEN'] = authToken; 
 
      } 
 
      return config; 
 
     }, 
 
     responseError: function(error) { 
 
      if (error.status === 401 || error.status === 403) { 
 
       TokenStorage.clear(); 
 
      } 
 
      return $q.reject(error); 
 
     } 
 
    }; 
 
}]); 
 

 
app.factory('AuthService', ['$http', 'TokenStorage', function($http, TokenStorage) { 
 
\t 
 
\t return { 
 
\t \t login : function(data, success, error) { 
 
\t \t \t success("token"); 
 
\t \t }, 
 
\t \t logout : function(success) { 
 
\t \t \t TokenStorage.clear(); 
 
      success(); 
 
\t \t }, 
 
\t \t current: function(success, error) { 
 
\t \t \t success("user"); 
 
\t \t } 
 
\t }; 
 
}]);

的index.html

<!DOCTYPE html> 
 
<html ng-app="salesmanApp"> 
 

 
<head> 
 
    <title>Login Demo</title> 
 

 
\t <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"> 
 
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap-theme.min.css"> 
 
    <link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.0/css/font-awesome.css"/> 
 

 

 
</head> 
 

 
<!-- define angular controller --> 
 
<body ng-controller="mainController"> 
 
<header> 
 
    <nav class="navbar navbar-default" role="navigation"> 
 
     <!-- Brand and toggle get grouped for better mobile display --> 
 
     <div class="navbar-header"> 
 
      <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar-collapse-1"> 
 
       <span class="sr-only">Toggle navigation</span> 
 
       <span class="icon-bar"></span> 
 
       <span class="icon-bar"></span> 
 
       <span class="icon-bar"></span> 
 
      </button> 
 
     </div> 
 

 
     <a class="navbar-brand" href="#"> 
 
      
 
      <span>Login Demo</span> 
 
     </a> 
 

 
     <div class="collapse navbar-collapse" id="navbar-collapse-1"> 
 

 
      <ul class="nav navbar-nav navbar-right" ng-show="authenticated"> 
 
       <li><a href="#/home">Home</a></li> 
 
       <li><a href="#" ng-click="logout()">Logout</a></li> 
 
      </ul> 
 

 
     </div> 
 
     <!-- /.navbar-collapse --> 
 
    </nav> 
 

 

 
</header> 
 
<div class="jumbotron"> 
 
    <div class="container"> 
 
     <div class="col-xs-offset-2 col-xs-8"> 
 
      <div ng-view></div> 
 
     </div> 
 
    </div> 
 
</div> 
 

 
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular-route.min.js"></script> 
 
<script src="https://code.jquery.com/jquery-2.1.3.min.js"></script> 
 
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script> 
 
<script src="https://rawgithub.com/gsklee/ngStorage/master/ngStorage.js"></script> 
 

 
<script src="app.js"></script> 
 
<script src="services.js"></script> 
 
<script src="controllers.js"></script> 
 

 
</body> 
 

 
</html>

回答

0

所以我最終擺脫$ rootScope.authenticated和$贊成調用AuthService一種新的方法scope.authenticated:AuthService.authenticated()。

我創建了一個名爲navController新的控制器:

app.controller('navController', ['$scope', '$location', '$rootScope', 'AuthService', '$timeout', function($scope, $location, $rootScope, AuthService, $timeout) { 

$scope.authenticated = AuthService.authenticated(); 
$scope.$watch(AuthService.authenticated, function(newVal, oldVal){ 
     $scope.authenticated = newVal; 
    }); 
$scope.logout = function() { 

    AuthService.logout(function() { 
     $scope.authenticated = false; 
     $location.path('/login'); 
    }); 
}; 

}]);

添加該控制器的報頭中的HTML:

<header ng-controller="navController"> 

$範圍$手錶是什麼,我需要得到註銷按鈕顯示出來,當我認證。

0

<!DOCTYPE html> 
 
<html ng-app="salesmanApp"> 
 

 
<head> 
 
    <title>Login Demo</title> 
 

 
\t <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"> 
 
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap-theme.min.css"> 
 
    <link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.0/css/font-awesome.css"/> 
 

 

 
</head> 
 

 
<!-- define angular controller --> 
 
<body ng-controller="mainController"> 
 
<header> 
 
    <nav class="navbar navbar-default" role="navigation"> 
 
     <!-- Brand and toggle get grouped for better mobile display --> 
 
     <div class="navbar-header"> 
 
      <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar-collapse-1"> 
 
       <span class="sr-only">Toggle navigation</span> 
 
       <span class="icon-bar"></span> 
 
       <span class="icon-bar"></span> 
 
       <span class="icon-bar"></span> 
 
      </button> 
 
     </div> 
 

 
     <a class="navbar-brand" href="#"> 
 
      
 
      <span>Login Demo</span> 
 
     </a> 
 

 
     <div class="collapse navbar-collapse" id="navbar-collapse-1"> 
 

 
      <ul class="nav navbar-nav navbar-right" ng-show="authenticated"> 
 
       <li><a href="#/home">Home</a></li> 
 
       <li><a href="#" ng-click="logout()">Logout</a></li> 
 
      </ul> 
 

 
     </div> 
 
     <!-- /.navbar-collapse --> 
 
    </nav> 
 

 

 
</header> 
 
<div class="jumbotron"> 
 
    <div class="container"> 
 
     <div class="col-xs-offset-2 col-xs-8"> 
 
      <div ng-view></div> 
 
     </div> 
 
    </div> 
 
</div> 
 

 
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular-route.min.js"></script> 
 
<script src="https://code.jquery.com/jquery-2.1.3.min.js"></script> 
 
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script> 
 
<script src="https://rawgithub.com/gsklee/ngStorage/master/ngStorage.js"></script> 
 

 
<script src="app.js"></script> 
 
<script src="services.js"></script> 
 
<script src="controllers.js"></script> 
 

 
</body> 
 

 
</html>