Toalp
Toalp

Reputation: 362

Access Global javascript variables inside AngularJS

I'm working on a site, and I started building it before I realized I needed some dynamic framework. After learning about AngularJS, I decided to use it, where I needed (not the whole site).

I have a very long script in JS, and I want to be able to get and set the variables from within AngularJS directives and controllers.

I found this answer, and it was quite good - I was able to get the variable from within the function. But when the variable changed outside the function, AngularJS' variable won't update.

My code looked something like this:

JS:

var app = angular.module('someName', []);
var currentPage = 'Menu';

app.controller('PageController', ['$window','$scope', function($window,$scope){

    this.currentPage = $window.currentPage;

    this.isPage = function(page){
        return (page == this.currentPage);
    };
}]);


function button1onClick(){
    currentPage = 'Game';
}

HTML:

<div ng-controller="PageController">
    <div id="Game" ng-show="page.isPage('Game')">
        ...
    </div>
    <div id="Menu" ng-show="page.isPage('Menu')">
        ...
    </div>
</div>

(button1onClick was called when I clicked some button on the page)

The idea is that I have two dives I want to switch between, using a globle variable. 'Menu' page was visible at first but upon clicking I was supposed to see only the 'Game' div.

The variable inside the controller didn't upadte, but was only given the initial value of currentPage.

I decided to use the $window service inside the isPage function, but this didn't work either. Only when I called a function that tested the $window.currentPage variable, the pages switched - like I wanted:

JS:

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

var currentPage = 'Menu';

app.controller('PageController', ['$window','$scope', function($window,$scope){

    this.isPage = function(page){
        return (page == $window.currentPage);
    };

    this.button2onClick = function() {
        $window.alert($window.currentPage);
    }
}]);


function button1onClick(){
    currentPage = 'Game';
}

HTML:

<button onclick="button1onClick()">CLICK ME</button> //Button 1
<div ng-controller="PageController">
    <button ng-click="page.button2onClick">CLICK ME</button> //Button 2

    <div id="Game" ng-show="page.isPage('Game')">
        ...
    </div>

    <div id="Menu" ng-show="page.isPage('Menu')">
        ...
    </div>
</div>

So the only way I was able to update the pages is to call a function that tests the variable, thus updating the variable in AngularJS.

Is there a way to access a global variable without needing to test it to update it?

Am I doing something wrong? I don't want to convert my whole site to AngularJS-style, I like the code the way it is. Is AngularJS not the framework for me?

EDIT:

some things to clear out:

  1. I'm new to AngularJS, so if you could explain what your answer does it would be great.

  2. The whole reason why I do this instead of redirecting to another page is not to shut down socket.io 's connection

Upvotes: 2

Views: 2671

Answers (4)

Imran
Imran

Reputation: 2089

It can be done using $rootScope. Variable initialize once can be accessible in other controllers.

function Ctrl1($scope, $rootScope) {
    $rootScope.GlobalJSVariableA= window.GlobalJSVariable;  }

Any controller & any view can access it now

function CtrlN($scope, $rootScope) {
    $scope.GlobalJSVariableA= $rootScope.GlobalJSVariableA; 
}

Upvotes: 0

Toalp
Toalp

Reputation: 362

After reading malix's answer and KKKKKKKK's answer, and after researching a bit, I was able to solve my problem, and even write a better looking code.

To switch divs as I wanted in the example, I used ui-router, almost exactly the way KKKKKKKK did. The only difference is that I change state programmaticly - $state.go('menu')

To access global variables in other places in my code, I had to re-structure my whole code to fit AngularJS's structure, and used a Service, similarly to malix's answer:

app.factory('Data', function(){
    var Data = {};
        //DEFINE DATA
    Data.stateChange = function(){};
    Data.menuData = {};
    Data.randomColors = ['#35cd96', '#6bcbef', '#E8E1DA', '#91ab01'];
        /RETURN DATA
    return Data;
});

Upvotes: 0

Kyle
Kyle

Reputation: 5557

OP, take a look at UI Router.

var app = angular.module("app", ['ui.router']);

app.config(['$urlRouterProvider', '$stateProvider', function($urlRouterProvider, $stateProvider) {
    $urlRouterProvider.otherwise('/main');

    $stateProvider.state('main', {
        controller: 'MainCtrl',
        templateUrl: 'main.html',
        url: '/main/'
    }).state('game', {
        controller: 'GameCtrl',
        url: '/game/',
        templateUrl: 'game.html'
    });
}]);

HTML links:

<a ui-sref="main">Go to Main</a>
<a ui-sref="game">Go to Game</a>

View injection

<div ui-view="">
</div>

Upvotes: 2

malix
malix

Reputation: 3572

You should not use $window as a map object. You should probably create a PageService:

angular.module('someName')
  .factory('Page', [function(){
    var currentPage = 'Menu';
    return {
      getPage: function() {
        return currentPage;
      },
      isPage: function(page) {
        return page === currentPage;
      },
      setPage: function(page) {
        currentPage = page;
      }
    }
  }]);

app.controller('PageController', ['Page','$scope', function(Page,$scope){

  this.currentPage = Page.getPage();
  this.isPage = Page.isPage;
  this.button10Click = function(){
    Page.setPage('Game');
  }
}]);

HTML

<div class="button" ng-click="page.button10Click()">Game</div>

Upvotes: 1

Related Questions