2013-10-02 233 views
6

我想通过一个正常的函数来访问一个全局变量,这有可能吗?AngularJs:如何访问控制器之外的全局变量?

我已经使用$ rootScope设置了一些变量,我试图通过回调函数来访问它。 该回调从控制器调用。我不想在该回调中通过$rootScope

有什么方法可以访问$rootScope.var

如果可以,我愿意使用服务。

请建议。

感谢

我试图访问rootScope如下:

function fbLandingCtrl($scope, $rootScope) { 
    $rootScope.isFBLoggedin = false; 
    $scope.login = function() { 
     console.log($rootScope.isFBLoggedin); 
     fbHelper.login(getUserInfo); 
     }; 

     function getUserInfo(){ 
      fbHelper.getUserInfo(updateStatus); 
     } 
     function updateStatus(userInfo){ 
      $rootScope.isFBLoggedin = true; 
      console.log($rootScope.isFBLoggedin); 
     } 
    } 

,我的服务是:

myapp.factory('FBService', [ '$rootScope', function ($rootScope) { 
    $rootScope.isFBLoggedin = false; // global variable 
    $rootScope.userName = null; 
    $rootScope.userEmail = null; 

    return { 

     getStatus: function() { 
      return $rootScope.isFBLoggedin; 
     }, 
     setStatus: function(status) { 
      console.log("Status:"+status); 
      return $rootScope.isFBLoggedin = status; 
     } 
     }; 
}]); 

它显示isFBLoggedin为真下updateStatus FN,但它是没有反映在视图上

我打印{{isFBLoggedin}}但是ts显示虚假

最后它的工作。

我跟着@ dluz的解决方案。

我也用$rootScope.$apply(function() {}})渲染视图

回答

5

请不要使用$ rootScope定义任何功能 - 这是非常糟糕的做法。请记住,$ rootScope毕竟是一个全局变量。

你可以通过服务的$ rootScope这样的:

<!doctype html> 
<html lang="en" ng-app="myApp"> 
    <head> 
<meta charset="UTF-8"> 
<title>Document</title> 
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script> 

    <script> 

    var myApp = angular.module('myApp', []); 

     myApp.controller('myAppCtrl', ['$scope', 'myService', function ($scope, myService) { 

     console.log(myService.getData()); 

}]) 

     myApp.factory('myService', [ '$rootScope', function ($rootScope) { 

     return { 

     getData: function() { 
      return $rootScope; 
     } 
     }; 
     }]) 


    </script> 

    </head> 
    <body ng-controller="myAppCtrl"> 

    </body> 
    </html> 

$rootScope exists, but it can be used for evil

作用域的角度形成了一个等级,在树的顶端从根范围prototypically继承。通常这可以被忽略,因为大多数视图都有一个控制器,因此也是一个范围。

偶尔会有一些数据想要让整个应用程序全局化。对于这些,您可以注入$ rootScope并像其他任何作用域一样设置值。由于作用域继承自根作用域,因此这些值可用于附加到像ng-show这样的指令的表达式,就像本地$ scope中的值一样。

当然,全局状态很糟糕,您应该谨慎使用$ rootScope,就像您希望在任何语言中使用全局变量一样。特别是,不要将它用于代码,只用于数据。如果您试图在$ rootScope上放置一个函数,那么将它放入一个可以注入需要的服务中并且更容易测试的服务几乎总是更好。

相反,不要创建一个服务,其唯一目的是存储和返回数据位。

修订ANSWER

A_J,我不知道什么是你的应用程序的场景。我需要看到更多的代码才能给出更好的答案,但请看下面的代码。也许它可以给你一些想法,你如何设计你的代码来访问service中的$rootScope

按下“Log me In”按钮,看看你的控制台。工作示例这里(http://jsbin.com/olOyaHa/1/

<!doctype html> 
<html lang="en" ng-app="myApp"> 
    <head> 
<meta charset="UTF-8"> 
<title>Document</title> 
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script> 

<script> 

    var myApp = angular.module('myApp', []); 

    myApp.controller('fbLandingCtrl', ['$scope', '$rootScope', 'loginService', function ($scope, $rootScope, loginService) { 

    $rootScope.isFBLoggedin = false; 

    $scope.login = function() { 
     console.log('Current login status', $rootScope.isFBLoggedin); 

     console.log(loginService.getUserInfo()); 

     loginService.login(loginService.getUserInfo()); 

     loginService.updateStatus(); 
     }; 


    }]); 


    myApp.factory('loginService', [ '$rootScope', function ($rootScope) { 

    return { 

     login: function() { 
      console.log('now I am logged in!'); 
      return $rootScope.isFBLoggedin = true; 
     }, 

     getUserInfo: function() { 
      return { 
       username: 'xmen', 
       role: 'admin', 
       logged: 'false' 
      }; 
     }, 

     updateStatus: function(userInfo){ 
      $rootScope.isFBLoggedin = true; 
      console.log('Current login status', $rootScope.isFBLoggedin); 
     } 
     }; 
    }]) 


    </script> 

</head> 
<body ng-controller="fbLandingCtrl"> 
    <button ng-click="login()">Log Me In</button> 
</body> 
</html> 
+0

确切地说,但我可以直接从正常的功能访问该服务? –

+1

您的“正常功能”在哪里定义?!?它会在'directive'或'controller'内,对吗?!?所以答案是YES,您只需要将该服务添加为您的指令或控制器的依赖项即可。如果你的普通函数是在其他地方定义的,那么这是一个代码设计问题,你需要检查你的逻辑。 –

+0

你是什么意思“正常功能”?任何角度范围之外的函数?听起来就像你有一个代码设计问题... – Scalpweb

2

如果添加$ rootScope作为控制器参考您可以访问控制器内$ rootScope.var:

function MyCtrl($scope, $rootScope, $routeParams /*, ... */) 
{ 
    /* Controller code and callback code here */ 
} 

它会工作,只要你的回调在您的控制器内部定义。

编辑:我们的讨论后,这里是如何定义rootScope里面的函数:

yourApp.run($rootScope/*, ResourceProvider ... */) { 
    $rootScope.yourFunction= function() { 
     /* The code of you functions */ 
    } 
} 
+0

谢谢,但我需要一个变种在一个回调函数,该控制器 –

+0

以外为什么你不能定义一个控制器内该回调? – Scalpweb

+0

,因为这是一个实用功能,也可以通过其他一些功能访问 –