2

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

Community
  • 1
  • 1
Toalp
  • 362
  • 1
  • 4
  • 15
  • i think you want to watch the var - try this prev answer http://stackoverflow.com/questions/20667012/angularjs-watch-window-variable – ade jones May 05 '16 at 15:47
  • I understand where you are coming from, but I think it's worth mentioning that you should consider refactoring. Angular is a framework and a methodology. I think you're going to run into these situations quite a bit and in the long run, will end up with a better, more maintainable app, if you refactor to use Angular. Your logic will stay relatively the same. I've done this before on a relatively modestly sized existing site and it took a day and a half or so. I was an Angular nOOb at the time and it really helped me learn Angular. – Mike Feltman May 05 '16 at 17:29
  • @MikeFeltman I understand why this is good, but I am using socket.io to keep the client connected (this is game site, requiring constant connection like chat), and I don't know if I can keep my code with both socket.io and AngularJS. PLUS, I can't seem to find anywhere how to write a normal webpage using Angular's structure. – Toalp May 05 '16 at 17:44

4 Answers4

2

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>
Kyle
  • 5,407
  • 6
  • 32
  • 47
  • 2
    @malix Okay, I think I know what OP wants. He'd be interested in ui.router. – Kyle May 05 '16 at 15:47
  • Yep. I agree. It doesn't answer his question but it fits his motive perfectly! – malix May 05 '16 at 16:39
  • This actually worked pretty well, and is exactly what I was looking for, but two things seem to be missing: --- 1. I still can't use global variables, the code I showed was only one of many places I needed global variable in my code, and --- 2. is there a way to change the ui-sref programmaticly, like `app.state="game"`? – Toalp May 05 '16 at 17:38
1

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>
malix
  • 3,566
  • 1
  • 31
  • 41
  • Thanks, your answer turned out to be exactly what I needed to get and set variables. My only question is why do you use `setPage` and `getPage` when you can just return the variable? (look at my answer) – Toalp May 06 '16 at 01:07
0

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;
});
Community
  • 1
  • 1
Toalp
  • 362
  • 1
  • 4
  • 15
0

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; 
}
Imran
  • 1,951
  • 1
  • 10
  • 7