Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a service object that doesn't share its values with controllers that consume it

Let's suppose I create a factory, service, or provider object like so

myApp.factory('myService', function() {
  return {
    counter: 0,
    increment: function() {
      console.log('counter: ' + (this.counter++))
    }
  };
});

And suppose I have a controller that depends on it

myApp.controller('myCtrl', function(myService) {
  $scope.incr = function() {
    myService.increment();
  };
}

And I apply this controller in different parts of the html

<div ng-controller="myCtrl">
  <button ng-click="increment()">increment</button>
</div>
...
<div ng-controller="myCtrl">
  <button ng-click="increment()">increment</button>
</div>

Right now, when I click on each button, the counter is universal and it goes 0, 1, 2, 3, ...

How can I write my factory, service, or provider so that each controller gets a different copy of the service object?

like image 372
kane Avatar asked Jun 19 '15 23:06

kane


1 Answers

Since factories are singletons you will need to use a method in your factory to create your service each time. Change your service to have a create method that returns your service that does the incrementing:

myApp.factory('myService', function() {
  return {
    create: function () {
      return { 
        counter: 0,
        increment: function() {
          console.log('counter: ' + (this.counter++));
        }
      };
    }
  };
});

myApp.controller('myCtrl', function($scope, myService) {
  var service = myService.create();
  $scope.incr = function() {
    service.increment();
  };
});

Also the controller method name doesn't match up to what is in the view:

<div ng-controller="myCtrl">
  <button ng-click="incr()">increment</button>
</div>
...
<div ng-controller="myCtrl">
  <button ng-click="incr()">increment</button>
</div>

Plunkr

like image 61
Wayne Ellery Avatar answered Sep 26 '22 23:09

Wayne Ellery