6

我正在尝试通过普通函数访问全局变量,这可能吗?

我已经使用 $rootScope 设置了一些 var,我正在尝试通过回调函数访问它。这个回调是从控制器调用的。我不想传递$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;
        }
       };
}]);

它在 updateStatus fn 下显示 isFBLoggedin 为真,但它没有反映在视图中

我正在打印{{isFBLoggedin}},但 ts 显示为假

最后它的工作。

我遵循@dluz 的解决方案。

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

4

2 回答 2

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 存在,但可用于作恶

Angular 中的作用域形成一个层次结构,原型继承自树顶部的根作用域。通常可以忽略这一点,因为大多数视图都有自己的控制器,因此也有自己的范围。

有时,您想让某些数据对整个应用程序具有全局性。对于这些,您可以像任何其他范围一样注入 $rootScope 并在其上设置值。由于作用域从根作用域继承,这些值将可用于附加到指令(如 ng-show)的表达式,就像本地 $scope 上的值一样。

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

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

更新的答案

A_J,我不确定您的应用程序的场景是什么。我需要查看更多代码才能为您提供更好的答案,但请查看下面的代码。也许它可以让您了解如何设计代码以$rootScopeservice.

按下“登录”按钮并查看您的控制台。这里的工作示例(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>
于 2013-10-02T13:21:30.440 回答
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 */
    }
}
于 2013-10-02T13:12:48.137 回答