AngularJS路由不更新菜单项,但正确加载URL和视图

AngularJS Routing not updating the menu items but loading the url and views correctly

本文关键字:加载 URL 视图 路由 更新 菜单项 AngularJS      更新时间:2023-09-26

我正在使用MEAN堆栈进行基于令牌的身份验证。当不存在令牌(即用户未登录时(,我的应用程序必须显示主页、登录和注册,当有令牌(即用户登录时(时,我的应用程序必须显示主页、我和注销。我所有的服务器端功能都可以正常工作,登录,注销。 地址栏中的URL重定向和视图的呈现正确发生,但菜单项没有相应地更新。只有当我点击手动刷新时,它才会更新。请帮忙!

索引.html(省略包括(:

<body ng-app="app">
    <div class="navbar navbar-inverse navbar-fixed-top" role="navigation" data-ng-controller="authCtrl">
       <!-- data-ng-controller="authCtrl" -->
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand" href="#/">Angular Restful Auth</a>
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li><a ng-href="#/">Home</a></li>
                    <li data-ng-show="token"><a ng-href="#/me">Me</a></li>
                    <li data-ng-hide="token"><a ng-href="#/login">Signin</a></li>
                    <li data-ng-hide="token"><a ng-href="#/register">Signup</a></li>
                    <li data-ng-show="token"><a ng-click="logout()">Logout</a></li>                    
                </ul>
            </div><!--/.nav-collapse -->
        </div>
    </div>
    <div class="container" ng-view="">
    </div> <!-- /container -->
    </body>

应用.js:

'use strict';
var app = angular.module('app', ['ngRoute', 'authControllers', 'authServices']);
var authControllers = angular.module('authControllers', []);
var authServices = angular.module('authServices', []);
var options = {};
options.api = {};
//dev URL
options.api.base_url = "http://localhost:3000";
app.config(['$locationProvider', '$routeProvider',
function($location, $routeProvider) {
  $routeProvider.
  when('/', {
    templateUrl: 'partials/home.html',
    controller: 'authCtrl'
  }).
  when('/login', {
    templateUrl: 'partials/signin.html',
    controller: 'authCtrl'
  }).
  when('/register', {
    templateUrl: 'partials/signup.html',
    controller: 'authCtrl'
  }).
  when('/me', {
    templateUrl: 'partials/me.html',
    controller: 'authCtrl'
  }).
  otherwise({
    redirectTo: '/'
  });
}]);
app.config(['$httpProvider', function ($httpProvider) {
  $httpProvider.interceptors.push('TokenInterceptor');
}]);
app.run(function($rootScope, $location, $window, AuthenticationService) {
  $rootScope.$on("$routeChangeStart", function(event, nextRoute, currentRoute) {
    //redirect only if both isAuthenticated is false and no token is set
    if (nextRoute != null && nextRoute.access != null && nextRoute.access.requiredAuthentication
      && !AuthenticationService.isAuthenticated && !$window.sessionStorage.token) {
        $location.path("/login");
      }
    });
  });

authControllers.js:

authControllers.controller('authCtrl', ['$scope', '$location', '$window', 'UserService', 'AuthenticationService',
function authCtrl($scope, $location, $window, UserService, AuthenticationService) {
  //Admin User Controller (login, logout)
  $scope.logIn = function logIn(username, password) {
    if (username !== undefined && password !== undefined) {
      UserService.logIn(username, password).success(function(data) {
        AuthenticationService.isLogged = true;
        $window.sessionStorage.token = data.token;
        $location.path("/me");
      }).error(function(status, data) {
        console.log(status);
        console.log(data);
      });
    }
  }
  $scope.token = $window.sessionStorage.token;
  $scope.me = function() {
    UserService.me(function(res) {      
      $scope.myDetails = res;
    }, function() {
      console.log('Failed to fetch details');
      $rootScope.error = 'Failed to fetch details';
    })
  };
  $scope.logout = function logout() {
    if (AuthenticationService.isAuthenticated) {
      UserService.logOut().success(function(data) {
        AuthenticationService.isAuthenticated = false;
        delete $window.sessionStorage.token;
        $location.path("/");
      }).error(function(status, data) {
        console.log(status);
        console.log(data);
      });
    }
    else {
      $location.path("/login");
    }
  }
  $scope.register = function register(username, password, passwordConfirm) {
    if (AuthenticationService.isAuthenticated) {
      $location.path("/me");
    }
    else {
      UserService.register(username, password, passwordConfirm).success(function(data) {
        $location.path("/login");
      }).error(function(status, data) {
        console.log(status);
        console.log(data);
      });
    }
  }
}]);
$scope.token = $window.sessionStorage.token;

此字符串不会将令牌绑定到存储属性。每次都应更新范围变量,如果不在摘要循环中,则显式调用 apply。

实际上,我尝试了一种不同的方法,在全球范围内进行一次甚至更好。在我的控制器中注入$rootScope并分配了会话存储令牌值。现在,它就像一个超级按钮,只需进行简单的更改$scope而无需在多个位置更新变量。

authControllers.controller('authCtrl', ['$rootScope','$scope', '$location', '$window', 'UserService', 'AuthenticationService',
function authCtrl($rootScope,$scope, $location, $window, UserService, AuthenticationService) {
$rootScope.token = $window.sessionStorage.token;
}]);