Jeff
Jeff

Reputation: 3407

Reusable AngularJS Service within an App

I'm very new to AngularJS, so it's possible I'm asking the entirely wrong question. What I'm trying to accomplish is create a reusable class with data binding in a single app. The following demonstrates what I'm trying to accomplish with a very simple example.

Say I want to create a counter with a value and an increment method. I can create a service and use it in a controller like so:

angular.module("fiddle", ["counter"])
.controller("MainCtrl", function($scope, counter) {
    $scope.counter = counter;
});

angular.module("counter", [])
.service("counter", function() {
    this.count = 0;
    this.increment = function(x) {
        this.count += x;
    };
});

Then I can display a view to add a counter:

<h1>Count: {{counter.count}}</h1>
<button ng-click="counter.increment(1)">Add 1</button>
<button ng-click="counter.increment(5)">Add 5</button>
<button ng-click="counter.increment(10)">Add 10</button>

This works fine for one counter, but what if I want to have multiple counters in the same controller? Since the service is a singleton, I can't do that. What's the best approach for creating something like this with Angular given that other services would be much more complex? Thanks!

http://jsfiddle.net/jeffaudio/ExASb/

Upvotes: 6

Views: 1774

Answers (2)

Shay Friedman
Shay Friedman

Reputation: 4868

Make your service support multiple counters:

angular.module("counter", [])
.service("counter", function() {
    // Counters is our object which service encapsulates
    this.counters = {};
    this.increment = function(name, x) {
        // If such counter is not set, set it.
        if (!this.counters[name]) { this.counters[name] = 0; }
        this.counters[name] += x;
    };
});

And then:

<button ng-click="counter.increment('count1', 1)">Add 1</button>
<button ng-click="counter.increment('count2', 5)">Add 5</button>
<button ng-click="counter.increment('count3', 10)">Add 10</button>

And bind the view to whatever counter you want...

Upvotes: 2

StuR
StuR

Reputation: 12218

To make a service not act like as a singleton you can do this:

angular.module("counter", [])
.service("counter", function() {
    var aCounter = function() {
        this.count = 0;
        this.increment = function(x) {
            this.count += x;
        };
    }
    return {
        getInstance: function () {
          return new aCounter();
        }
    };
});

And then manage your counters from your controller, e.g:

function myCtrl($scope, counter) {
    $scope.counter1 = counter.getInstance();
    $scope.counter2 = counter.getInstance();
}

http://jsfiddle.net/KLDEZ/

Upvotes: 9

Related Questions