【问题标题】:Angular JS Root ScopeAngular JS 根范围
【发布时间】:2014-04-08 08:22:24
【问题描述】:

我正在视图层使用 Angular js。我需要使用一些全局变量,这些变量将被我的应用程序中的所有控制器方法使用和修改:

 var app = angular.module('myWebservice', ['ngCookies']).run(
    function($rootScope) {
        $rootScope.authToken = null; }); 

 app.controller('UserController', function($cookieStore, $scope, $location,
    $routeParams, $http, $timeout, $rootScope) {

        $scope.login= function() {

    $http.defaults.headers.post = {'Accept' : 'application/json',
        'Content-Type' : 'application/json'};

    $http.post('/myServise/api/user/login-user', {
                        emailId : $scope.username,
                        password : $scope.password

                    }).success(function(data, status) {
                        if (status == 200) {
            $rootScope.authToken = data.object.authToken;
                }).error(function(data, status) {           
                        console.debug(data);});
        }// Else end

};// End Login


app.controller('MerchantController', function($cookieStore, $scope, $location,
    $routeParams, $http, $timeout, $rootScope) {

    $scope.getRootScopeValues = function() 
    //$scope.getRootScopeValues = function($rootScope) 
    {
        $scope.token = $rootScope.authToken;
        console.log($scope.token);// Undefined 
        console.log($rootScope.authToken);// Undefined 
    }
});

我是 Angular JS 的新手,我也尝试过使用服务,但我不知道为什么我无法访问全局变量 (authToken)。请帮助我,我被困在这一点上....提前谢谢...

【问题讨论】:

  • 这可能是因为您尝试在$http 帖子设置之前访问authToken
  • 首先我调用 login 并在登录方法中我得到 authToken 然后在设置为 rootScope 之后如果我登录我得到 authToken 的值。
  • 我的意思是,在UserController 中的 HTTP 请求完成之前,您可能正在尝试 tp console.log MerchantController 中的 authToken。
  • 不不,实际上当我用登录完成执行时,只有我在调用 getRootScopeValues 函数。当用户登录时,他点击我写过 ng-click="getRootScopeValues()" 的链接。我也可以相应地查看服务器日志。
  • $http.post() 返回一个承诺,这意味着如果 authToken 是异步设置的(即在对 login() 的调用完成之后。所以...

标签: javascript angularjs angularjs-directive angularjs-scope angular-ui-bootstrap


【解决方案1】:

我不确定您的应用程序是如何工作的,但看起来您遇到了异步调用问题(当 $http 工作时,您正试图访问尚未设置的变量)。请查看有关Asynchronous calls 的答案。也许这是你的情况?另外我应该注意,使用 $rootScope 总是一个坏主意。尽量避免它。您应该改用 service,它也是一个单例对象,并且始终是一种更好且可维护的方法。

【讨论】:

  • + 1. 单身服务绝对是必经之路。
  • 我也尝试过使用服务,但结果相同“未定义”
  • 在这里使用 rootScope 或服务不是问题。使用异步调用的问题。您应该使用 $http 的回调或 Promise 来处理结果。
  • app.service('shared', function() { var sharedData = { authToken : ''}; return { setAuthToken : function(v) { sharedData.authToken = v; }, update : function () { return sharedData;} } });
【解决方案2】:

我需要使用一些全局变量,这些变量将被我的应用程序中的所有控制器方法使用和修改

实现此目的的最佳方法是使用服务,但如果您想将其保留在 $rootScope 中,则不必这样做

我也尝试过使用服务,但结果相同“未定义”

由于 authToken 的调用是异步的,控制器可以在令牌从远程服务器返回之前运行。

您可以将令牌检索逻辑作为“解析”字段添加到路由定义中,如下所示:

.config(function($routeProvider, $locationProvider) {
  $routeProvider
   .when('/your/route', {
    templateUrl: 'book.html',
    controller: 'BookController',
    resolve: {      
      token: function() {
        //return a promise with the token here
      }
    }
  })

但是,这对您的情况不利,因为您必须为每条路线设置“解析”。如果您使用支持嵌套路由的AngularUI Route,您只需将“解决”添加到根状态/路由即可。这是我在项目中一直使用的。

如果您不使用AngularUI Route,还有另一种方法。您可以将 $http.post 的返回值分配给 $rootScope 中的变量,例如$rootScope.tokenPromise。 $http.post 返回的是promise,可以使用'then;方法来注册回调,这些回调将接收一个参数——一个代表响应的对象。

在您的控制器中,您将添加一些额外的行,您将像这样异步获取令牌

app.controller('MerchantController', function($cookieStore, $scope, $location,
    $routeParams, $http, $timeout, $rootScope) {

    $rootScope.tokenPromise.then( function(token){
        console.log(token); //depends on the returned data structure

    } )

});

在您的应用程序“运行”块中,您必须在 $rootScope.tokenPromise 处创建一个承诺。您可以使用 $http 检索令牌并在 run 块中获取承诺,或者创建待处理的承诺并在其他地方的其他地方检索令牌,之后您可以解决承诺。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-07
    • 2016-05-30
    • 1970-01-01
    • 2016-03-09
    • 1970-01-01
    • 1970-01-01
    • 2017-01-01
    • 1970-01-01
    相关资源
    最近更新 更多