Reputation: 1643
I have tens of AngularJS Factories which have a lot in common. So I'm trying to make a base class and subclass it.
But I've noticed that the subclasses are sharing member variables of the base class.
I've made an example on http://jsbin.com/doxemoza/2/edit, the code is also posted here:
HTML:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.3/angular.min.js"></script>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body ng-app="demo" ng-controller="MainCtrl">
<p>ChildService: {{value1}}</p>
<p>AnotherChildService : {{value2}}</p>
</body>
</html>
JavaScript:
angular.module('demo', []);
var demo = angular.module('demo').controller('MainCtrl', function ($scope, ChildService, AnotherChildService) {
$scope.value1 = ChildService.getPrivateVar();
$scope.value2 = AnotherChildService.getPrivateVar();
});
var Base = function () {
var Service = {};
Service.privateVar = 0;
Service.setPrivateVar = function (value) {
Service.privateVar = value;
}
Service.getPrivateVar = function () {
return Service.privateVar;
}
return Service;
};
demo.factory('BaseService', Base)
demo.factory('ChildService', function (BaseService) {
var ChildService = Object.create(BaseService);
ChildService.setPrivateVar(1);
return ChildService;
});
demo.factory('AnotherChildService', function (BaseService) {
var AnotherChildService = Object.create(BaseService);
AnotherChildService.setPrivateVar(2);
return AnotherChildService;
});
My expected output is:
ChildService: 1
AnotherChildService : 2
But instead I get:
ChildService: 2
AnotherChildService : 2
I think ChildService
and AnotherChildService
are sharing the same privateVar
, so I got the same value for them.
How should I change the code to make them use different instance of privateVar
?
Thanks
Upvotes: 3
Views: 1495
Reputation: 134
I had that same problem, and was solved when a declared my BaseService this way:
demo = angular.module('demo', []);
demo.factory('BaseService', function(){
return {
privateVar: 0,
setPrivateVar: function (value) {
this.privateVar = value;
},
getPrivateVar: function () {
return this.privateVar;
}
}
});
My "child" services are like yours. Everything works very fine.
Upvotes: 1
Reputation: 2200
I use something like this:
angular.module('app')
.controller('ParentController', ['$scope', 'dataService', function ($scope, dataService) {
//controller logic here
}])
.controller('ChildController', ['$scope', '$controller', 'SomeDataService', function ($scope, $controller, SomeDataService) {
//extend your parentcontroller
$scope.init = function () {
//do something
}
angular.extend(this, $controller('ParentController', {
$scope: $scope,
dataService: SomeDataService
}));
}])
.factory('BaseDataService', ['logger', function (logger) {
var privateArray = [];
return {
publicFunction: function(){ return privateArray; },
publicVar: "some var"
}
}])
.factory('SomeDataService', ['BaseDataService', function (dataService) {
var service = angular.extend({}, dataService);
service.privateFunction = function () {
//some code
}
service.privateVar= "some value";
return service;
}]);
I combined all of them in this example.
Hope this helps.
Edit: this uses the mixin pattern described in this post
Upvotes: 1