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

3
  • i think you want to watch the var - try this prev answer stackoverflow.com/questions/20667012/… Commented May 5, 2016 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. Commented May 5, 2016 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. Commented May 5, 2016 at 17:44

4 Answers 4

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>
Sign up to request clarification or add additional context in comments.

3 Comments

@malix Okay, I think I know what OP wants. He'd be interested in ui.router.
Yep. I agree. It doesn't answer his question but it fits his motive perfectly!
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"?
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>

1 Comment

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)
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;
});

Comments

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; 
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.