Angular JS Root Scope

时间:2014-04-07 05:27:40

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

我在视图层使用角度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)。请帮助我,我在这一点上陷入困​​境......提前致谢...

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

  

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

实现这一目标的最佳方法是使用服务,但如果您希望将其保留在$ rootScope

,则无需使用
  

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

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

您可以将令牌检索逻辑添加到路径定义中作为'resolve'字段,如下所示:

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

然而,这对你的情况并不好,因为你必须为每条路线设置'resolve'。如果您使用支持嵌套路由的AngularUI Route,则只需将“resolve”添加到根状态/路由即可。这就是我在我的项目中一直使用的。

如果你没有使用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

    } )

});

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