Search code examples
javascriptangularjsangularjs-serviceangularjs-controlleras

Shared variables and multiple controllers AngularJS


I have multiple controllers on a small app I'm writing, and I have successfully shared a 'selected' variable between the controllers like so.

app.service('selectedEmployee', function () {
    var selected = null;

    return 
    { 
        getSelected: function() {
            return selected;
        },
        postSelected: function(employee) {
            selected = employee;
        }
    };

});

I have a side nav bar with a list of employees. When I click on an employee I call the postSelected function then the getSelected to set $scope.selected.

$scope.selectEmployee = function(employee) {

   //Calling Service function postSelected
    selectedEmployee.postSelected(employee);

    $scope.selected = selectedEmployee.getSelected();

    if ($mdSidenav('left').isOpen()) {
        $mdSidenav('left').close();
    }

}

I have a third controller for my main content area, and this is where I don't understand what to do. I want information from the selected employee to be displayed, but angular is compiling the whole page before the first employee has a chance to get set as selected, and subsequent selections of an employee aren't reloading the main content page (because I haven't told them to I think). Here's my main content controller:

app.controller('mainContentController', ['$scope','selectedEmployee',
    function ($scope, selectedEmployee) {
        $scope.selected = selectedEmployee.getSelected();
        console.log($scope.selected);
    }
]);

My main content view is very simple right now

<h2>{{selected.firstName}}{{selected.lastName}}</h2>

My question is how I can tell one controller to effectively update its partial view so that when I select an employee it displays information.

GitLab repo


Solution

  • Don't rely on messy broadcasts if your goal is simply to display & modify the data in the controller's template.

    Your controllers do NOT need to "know" when the Service or Factory has updated in order to use it in the template as Angular will handle this for you, as you access the data via dot notation. This is the important concept which you should read more about.

    This Fiddle shows both ways of accessing the data, and how using the container object in the template causes Angular to re-check the same actual object on changes - instead of the primitive string value stored in the controller:

    http://jsfiddle.net/a01f39Lw/2/

    Template:

    <div ng-controller="Ctrl1 as c1">
        <input ng-model="c1.Bands.favorite" placeholder="Favorite band?">
    </div>
    <div ng-controller="Ctrl2 as c2">
        <input ng-model="c2.Bands.favorite" placeholder="Favorite band?">
    </div>
    

    JS:

    var app = angular.module("app", []);      
    
    app.factory('Bands', function($http) {
        return {
            favorite: ''
        };    
    });
    
    app.controller('Ctrl1', function Ctrl1(Bands){
        this.Bands = Bands;
    });
    app.controller('Ctrl2', function Ctrl2(Bands){
        this.Bands = Bands;
    });