Jerald
Jerald

Reputation: 4048

Singleton controller in AngularJs

I have a directive: in template:

<territorial-selector></territorial-selector>

in js:

app.directive('territorialSelector', function() {
    return {
        restrict: 'E'
        ,templateUrl: 'partials/territorial-selector.html'
        ,controller: 'TerritorialSelectorController'
    };
};

As you can see the directive use "TerritorialSelectorController"

In another one place I have a button that should execute method loadTerritories() from TerritorialSelectorController. I created this button:

<button ng-controller="TerritorialSelectorController" ng-click="loadTerritories()">BUTTON</button>

The problem that in this case TerritorialSelectorController creates two times. Here is the code of TerritorialSelectorController:

app.controller('TerritorialSelectorController', ['$scope', function($scope) {
    alert('AAAAA'); // I have alert two times
}]);

And I need only one object of the controller.

Upvotes: 6

Views: 3434

Answers (1)

Michael Oryl
Michael Oryl

Reputation: 21642

If you want the functionality to work as a singleton, then you will need it to be inside a service that your controllers then access. Controllers are not singletons; you can have many, many instances of the same basic controller in your code.

If you instead create a service, then the common data/functionality that each controller must share can be placed, and accessed, through that service.

Here's a Plunk demo that shows two controllers sharing data through a service. It's not two controllers of the same type, but it will show you the basics of how services work.

Here's some code from the demo, as well. Controller:

app.controller('SunListCtrl', function($scope, List, $log) {
  $scope.items = List.getList();

  $scope.$on('updatedList', function() {
    $scope.items = List.getList();
    $log.info('List has been updated. Size = ' + $scope.items.length);
    $log.info('\tNow set to: ' + $scope.items);
  });
});

Service:

app.service('List', function($rootScope, $log) {
  service = {}; // the service object we'll return

  var dateValue = 'date';
  var geoValue = 'geo';
  var theList = [];

  service.setGeo = function(data) {
    geoValue = data;
    updateList();
  }

  service.setDate = function(data) {
    dateValue = data;
    updateList();
  }

  function updateList() {
    theList = [dateValue, geoValue];
    $rootScope.$broadcast('updatedList');  // broadcasts the update to listeners 
  }

  service.getList = function() {
    return theList;
  }

  return service;
});

Upvotes: 11

Related Questions