2013-10-02 7 views
6

Я пытаюсь получить доступ к глобальной переменной через обычную функцию, возможно ли это?AngularJs: Как получить доступ к глобальным переменным за пределами контроллера?

Я установил некоторый var, используя $ 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

областей в виде угольника иерархии, прототипически наследуя от корня объема в верхней части дерева. Обычно это можно игнорировать, поскольку большинство представлений имеют контроллер и, следовательно, область действия.

Иногда есть части данных, которые вы хотите сделать глобальными для всего приложения. Для этого вы можете вводить $ rootScope и устанавливать значения на нем, как и в любой другой области. Поскольку области действия наследуются от области корня, эти значения будут доступны выражениям, прикрепленным к директивам, таким как ng-show, точно так же, как значения в локальной области $ scope.

Конечно, глобальное состояние отстойно, и вы должны использовать $ rootScope экономно, как и вы (будем надеяться) использовать с глобальными переменными на любом языке. В частности, не используйте его для кода, а только данные. Если у вас возникнет соблазн поставить функцию на $ rootScope, почти всегда лучше разместить ее в сервисе, который можно вставить туда, где это необходимо, и более легко протестировать.

И наоборот, не создавайте службу, единственной целью которой является сохранение и возврат бит данных.

ОБНОВЛЕНО ОТВЕТ

a_j, я не уверен, что сценарий вашего приложения. Мне нужно будет увидеть больше кода, чтобы дать вам лучший ответ, но, пожалуйста, взгляните на приведенный ниже код. Возможно, это может дать вам представление о том, как вы можете создать свой код для доступа к $rootScope внутри service.

Нажмите кнопку «Войти в систему» ​​и взгляните на консоль. Работа здесь пример (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

Где ваша "нормальная функция"???? Он будет либо внутри «директивы», либо «контроллера», правильно?!? Таким образом, ответ «ДА», вам просто нужно добавить эту службу в зависимость от вашей директивы или контроллера. Если ваша нормальная функция определена где-то в другом месте, это проблема проектирования кода, и вам нужно будет пересмотреть свою логику. –

+0

Что значит «нормальная функция»? Функция вне любого угла? Похоже, у вас есть проблема с дизайном кода ... – Scalpweb

2

Вы можете получить доступ к $ rootScope.var внутри контроллера, если вы добавили $ rootScope в качестве ссылки контроллера:

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

Он будет работать до тех пор, как ваш обратный вызов определяется внутри вашего контроллера.

EDIT: после нашего обсуждения, вот как определить функцию внутри rootScope:

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

Спасибо, но мне нужно, что переменная в функции обратного вызова, за пределами этого контроллера –

+0

Почему вы не можете определить этот обратный вызов внутри контроллера? – Scalpweb

+0

, потому что это служебная функция, доступ к некоторым другим функциям тоже –

Смежные вопросы