Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS - Shared state between controllers?

Tags:

angularjs

I know there are other similar questions on how to pass data between Angular controllers.

What I wonder is how to deal with this in a view..

Lets say I have a UserController for login, registration etc. And an AppController for the actual app functionallity .

The UserController would be fairly easy, its sort of standalone from the rest. But what if the app needs to know about stuff from the user controller?

Lets say the app view needs to hide/show stuff depending on if the user is logged in or not. Or it could be if the user is male or female etc.

Should the app model keep its own copy of the user model state? e.g. appModel.isLoggedIn , appModel.gender etc ?

feels a bit redundant, but at the same time more testable.

So what is the correct way to do this?

like image 869
Roger Johansson Avatar asked Jul 04 '13 12:07

Roger Johansson


People also ask

How to share data between two Controllers in AngularJS?

Approach: To share data between the controllers in AngularJS we have two main cases: Share data between parent and child: Here, the sharing of data can be done simply by using controller inheritance as the scope of a child controller inherits from the scope of the parent controller.

What is controlleras in AngularJS?

In AngularJS, a Controller is defined by a JavaScript constructor function that is used to augment the AngularJS Scope. Controllers can be attached to the DOM in different ways.

Can we have two controllers in AngularJS?

An AngularJS application can contain one or more controllers as needed, in real application a good approach is to create a new controller for every significant view within the application.


2 Answers

To further specify the answer @GoloRoden gave, this is an example of how you can share state values across all controllers taking the service as a dependency.

App.factory('formState', formState);

function formState() {        

    var state = {};

    var builder = "nope";
    var search = "nope";

    state.builder = function () {
        return builder;
    };

    state.search = function () {
        return search;
    };

    state.set = {
        'builder': function (val) {
            builder = val;
        },
        'search': function (val) {
            search = val;
        }
    };

    return {
        getStateManager: function () {
            return state;
        }
    };
}

App.controller('builderCtrl', builderCtrl);

builderCtrl.$inject = ['formState']
function builderCtrl(formState) {
    var stateManager = formState.getStateManager();

    activate();

    function activate() {
        console.log("setting val in builder");
        stateManager.set.search("yeah, builder!");

        console.log("reading search in builder: " + stateManager.search());
        console.log("reading builder in builder: " + stateManager.builder());
    }
}

App.controller('searchCtrl', searchCtrl);

searchCtrl.$inject = ['formState']
function searchCtrl(formState) {
    var stateManager = formState.getStateManager();

    activate();

    function activate() {
        console.log("setting val in search");
        stateManager.set.search("yeah, search!");

        console.log("reading search in search: " + stateManager.search());
        console.log("reading builder in search: " + stateManager.builder());
    }
}
like image 116
pluralMonad Avatar answered Jun 23 '23 01:06

pluralMonad


Short answer

Create a service, see Creating Services for details.

Long answer

Services are - per se - application-wide singletons, hence they are perfect for keeping state across views, controllers & co.:

app.factory('myService', [ function () {
  'use strict';
  return {
    // Your service implementation goes here ...
  };
}]);

Once you have written and registered your service, you can require it in your controllers using AngularJS' dependency injection feature:

app.controller('myController', [ 'myService', '$scope',
  function (myService, $scope) {
  'use strict';
  // Your controller implementation goes here ...
}]);

Now, inside your controller you have the myService variable which contains the single instance of the service. There you can have a property isLoggedIn that represents whether your user is logged in or not.

like image 20
Golo Roden Avatar answered Jun 23 '23 00:06

Golo Roden