1

As per document: Angular service are singleton

I am creating a time-tracking project in which i want to add multiple task

<ul>
    <li ng-repeat="item in data track by $index" >
        <label>Project Name</label>
        <input type="text" ng-model="item.project"/>
        <label>Start Time</label>
        <input type="text" ng-model="item.start"/>
        <label>End Time</label>
        <input type="text" ng-model="item.finish"/>
    </li>
</ul>

<a ng-click="addEntry();">Add Item</a>

and this is my controller

controller("DashboardCtrl", ['$scope', 'Entry', function ($scope,Entry) {
        $scope.data = [];

        $scope.addEntry = function() {
            $scope.data.push(Entry);
            //$scope.data.push(new jEntry());
        }

    }])

and my service

.service('Entry', [function(){
        this.project = "";  
        this.start = "";  
        this.finish = "";

    }]);

My problem is that when i use javascript constructor(jEntry)

function jEntry() {
        this.project = "";  
        this.start = "";  
        this.finish = "";
    }

for creating new task, it works fine, while using service all tasks behave as they are bind to singleton.

So my question is what is the angular way to perform this task?

DEMO

1 Answer 1

2

You could have your service return an instantiable function.

.service('Entry', [function(){
     return function() {
          this.project = "";  
          this.start = "";  
          this.finish = "";
     }
}]);

Use like $scope.data.push(new Entry());

http://plnkr.co/edit/XTRtWbv1VS5gMmkn7B7e?p=preview

It does kind of defeat the purpose of having a service though. You could just as well do this inside the controller.

A better way would be to have the service track the entries (as opposed to pushing them into the scope directly)

To track the entries in the service:

Knowing that the entries are a singleton, you can attach the entries themselves to the singleton, and add methods to manipulate them. Like so:

.service('Entry', [function(){
  var self = this;
  self.entries = [];
      
  this.add = function() {
    self.entries.push({
      project: "",
      start: "",
      finish: ""
    })
  }
}]);

Instead of adding the entries object to the scope, you now attach the whole Entry singleton:

$scope.data = Entry;

The ng-click function will then change to data.add(). Additionally, you now loop over data.entries instead of just entries. This will allow you to use the Entry object in other controllers while retaining all its data.

Here's a new plunkr: http://plnkr.co/edit/5hs99xMQ3ZOiAWpesD5V?p=preview

Now you can start adding more functions to Entry, for example you can add RESTful methods to store additions in your DB. Or maybe you want methods to remove entries.

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

2 Comments

"service track the entries" could you please suggest how do i reference those entries.
added a simple example

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.