Say I want more than one instance of a user service (selectedUser & currentUser), they provide the same functionality. Currently I just get around the problem by creating two services that pull their definition from a local function:
angular.module('myUserModule', [])
.factory('userFactory', ['$http', '$q', function ($http, $q) {
return function getUser(userId) {
return new $q(function (resolve) {
//Gets the user with the provided userId
}
}
}])
.value('currentUserId', '')
.value('selectedUserId', '')
.service('currentUserService', ['userFactory', 'currentUserId', User])
.service('selectedUserService', ['userFactory', 'selectedUserId', User]);
function User(userFactory, userId) {
var self = this;
var promise = userFactory(userId);
promise.then(function setUserSuccess(result) {
self.user = result;
}
}
Just wondering how other people have approached this problem.
Updated: Just to clarify that I am making use of these services as singletons too.
In an unrelated question the solution ended up using a factory that creates multiple instances:
what is the scope of a service in angularjs?
Use the Factory Pattern.
In essence, if you have a User service, you can use a factory to return a unique instance of the service.
function User(userId, $http) {
var self = this;
$http.get('/api/user/', {userId: userId}).success(function(result) {
self.details = result.data;
}):
}
userFactory.$inject = ['$http'];
function userFactory($http) {
return function(user) {
return new User(user, $http);
}
}
angular.module('app').factory('user', userFactory);
But for this example, you can just use $resource
. This is a built in angular factory that returns unique Resource instances.
You can use use your factory as an API to return a collection of objects with getter and setter methods.
You can declare new Factory by using the new
keywords. However, it is preferable to encapsulate the creation of an instance into a getter method.
Service
(function(){
function userFactory($http, $q){
//Create our userFactory
function userFactory(num){
this.num = num;
};
//Retrieve some user data for example
function getUser(id){
return new $q(function(resolve){
resolve({id: id, data: [1,2,3,4]});
});
}
//Another method
function awesome(){
console.log('Awesome method called by : ' + this.num);
}
//Set method by prototyping
userFactory.prototype.getUser = getUser;
userFactory.prototype.awesome = awesome;
return {
//Use get method to return a new instance of our factory
get: function(){
//Pass a random id for our factory
return new userFactory(Math.ceil(Math.random() * 100));
}
}
}
angular
.module('app')
.factory('UserFactory', userFactory);
})();
The you can create your own instance by using the .get() method :
Controller
(function(){
function Controller($scope, UserFactory) {
var factoryA = UserFactory.get()
var factoryB = UserFactory.get();
console.log('A num instance ' + factoryA.num);
console.log('B num instance ' + factoryB.num);
factoryA.getUser(1).then(function(data){
console.log(data);
});
factoryB.awesome();
console.log('Equality = ' + angular.equals(factoryA, factoryB));
}
angular
.module('app', [])
.controller('ctrl', Controller);
})();
(function(){
function Controller2($scope, UserFactory) {
var factoryC = UserFactory.get()
console.log('C num instance ' + factoryC.num);
}
angular
.module('app')
.controller('ctrl2', Controller2);
})();
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.