6

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/

2 Answers 2

9

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/

Sign up to request clarification or add additional context in comments.

1 Comment

Out of curiosity, is this considered good/bad practice or does it just come down personal preference?
2

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...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.