Edit in response to comment: Looks like if you simply return the constructor function for your object you can do this, then access the prototype through the call to the service.
Quick explanation, in the example, clicking "Get Again" will call the prototype function changeHelloWorldString and update the string with the name of the control. Once you click "Change Prototype", that changeHelloWorldString function is changed to append " [PROTOTYPE CHANGE]" to the string. Clicking either "Get Again" button will demonstrate that the prototype change made in the second controller affected the prototype chain for the object in both controllers.
See the example below:
angular.module('myModule2', [])
.factory('myService', function() {
function FactoryConstructor(thirdFunction) {
this.helloWorldFunction = function() {
return this.helloWorldString;
}
this.thirdFunction = thirdFunction;
}
FactoryConstructor.prototype.helloWorldString = 'Hello World';
FactoryConstructor.prototype.changeHelloWorldString = function(newString) {
this.helloWorldString = newString;
};
FactoryConstructor.prototype.changeThirdFunction = function(newFunction) {
this.thirdFunction = newFunction;
}
return FactoryConstructor;
})
.controller('ctrl1', function($scope, myService) {
var factoryResult = new myService(function() {
this.helloWorldString += ' first';
});
$scope.hwString = factoryResult.helloWorldString;
$scope.hwString2 = factoryResult.helloWorldFunction();
// console.log(factoryResult instanceof myService) //tested true
$scope.getAgain = function() {
factoryResult.changeHelloWorldString('ctrl1 String');
factoryResult.thirdFunction();
$scope.hwString = factoryResult.helloWorldString;
$scope.hwString2 = factoryResult.helloWorldFunction();
}
})
.controller('ctrl2', function($scope, myService) {
var factoryResult = new myService(function() {
this.helloWorldString += ' second';
});
$scope.hwString = factoryResult.helloWorldString;
$scope.hwString2 = factoryResult.helloWorldFunction();
// console.log(factoryResult instanceof myService) //tested true
$scope.getAgain = function() {
factoryResult.changeHelloWorldString('ctrl2 String');
factoryResult.thirdFunction();
factoryResult.changeThirdFunction(function() {
this.helloWorldString += ' third';
});
$scope.hwString = factoryResult.helloWorldString;
$scope.hwString2 = factoryResult.helloWorldFunction();
}
$scope.changePrototype = function() {
myService.prototype.changeHelloWorldString = function(newString) {
this.helloWorldString = newString + " [PROTOTYPE CHANGE]";
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='myModule2'>
<div ng-controller='ctrl1'>
<div>{{hwString}}</div>
<div>{{hwString2}}</div>
<button ng-click='getAgain()'>Get again</button>
</div>
<div ng-controller='ctrl2'>
<div>{{hwString}}</div>
<div>{{hwString2}}</div>
<button ng-click='getAgain()'>Get again</button>
<button ng-click='changePrototype()'>Change Prototype</button>
</div>
</div>
Another excellent explanation of this is found in this answer. This may show a better/cleaner way to do what this example shows by using a provider (which service and factory are both derived from, see the side note from the author).
Rest of original post below for background
Angular services are singletons that can be injected into many places.
So if you do this:
angular.module('myModule', [])
.service('myService', function() {
var myService = this;
this.helloWorldString = 'Hello World String';
this.helloWorldFunction = function() {
return myService.helloWorldString;
}
})
.controller('main', function($scope, myService) {
$scope.getAgain = function() {
$scope.hwString = myService.helloWorldString;
$scope.hwString2 = myService.helloWorldFunction();
}
$scope.getAgain();
})
.controller('notMain', function($scope, myService) {
myService.helloWorldString = 'edited Hello World String';
$scope.hwString = myService.helloWorldString;
$scope.hwString2 = myService.helloWorldFunction();
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='myModule'>
<div ng-controller='main'>
<div>{{hwString}}</div>
<div>{{hwString2}}</div>
<button ng-click='getAgain()'>Get again</button>
</div>
<div ng-controller='notMain'>
<div>{{hwString}}</div>
<div>{{hwString2}}</div>
</div>
</div>
You'll notice that initially the two are different, because the first pair was obtained before the change, but the change made in the second controller DOES, in fact, affect the first. Just click the Get Again button and it will re-pull the info from the service and it now matches, proving they're the same object despite being injected into two different controllers.
Looks like what you really want is a factory (although this is mostly semantics, you can change out "factory" for "service" in this next example and it will produce the same result. This can also be seen in the Angular docs themselves. The documentation for a service never actually uses .service, it uses .factory throughout). That way you can, in essence, construct a new instance of your factory object when you call, in this example, 'myService(...)'. Using those function parameters, you can customize properties, including functions, of the object you return, as you can see in the example.
angular.module('myModule2', [])
.factory('myService', function() {
return function(stringInput, thirdFunction) {
return {
helloWorldString: stringInput,
helloWorldFunction: function() {
return this.helloWorldString;
},
thirdFunction: thirdFunction
}
}
})
.controller('ctrl1', function($scope, myService) {
var factoryResult = myService('Hello World String', function () {
this.helloWorldString += ' first';
});
$scope.hwString = factoryResult.helloWorldString;
$scope.hwString2 = factoryResult.helloWorldFunction();
$scope.getAgain = function() {
factoryResult.thirdFunction();
$scope.hwString = factoryResult.helloWorldString;
$scope.hwString2 = factoryResult.helloWorldFunction();
}
})
.controller('ctrl2', function($scope, myService) {
var factoryResult = myService('new Hello World String', function () {
this.helloWorldString += ' second';
});
$scope.hwString = factoryResult.helloWorldString;
$scope.hwString2 = factoryResult.helloWorldFunction();
$scope.getAgain = function() {
factoryResult.thirdFunction();
$scope.hwString = factoryResult.helloWorldString;
$scope.hwString2 = factoryResult.helloWorldFunction();
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='myModule2'>
<div ng-controller='ctrl1'>
<div>{{hwString}}</div>
<div>{{hwString2}}</div>
<button ng-click='getAgain()'>Get again</button>
</div>
<div ng-controller='ctrl2'>
<div>{{hwString}}</div>
<div>{{hwString2}}</div>
<button ng-click='getAgain()'>Get again</button>
</div>
</div>