I have a service which will return the name of factory. I already injected all the factories into controller. I need to use the variable to call the method inside that factory. I know i can use
if(var == 'factoryname') {
factoryname.method()
}
but i don't want those if conditions because i have number of factories. Is there any way to call a method inside that factory like in java script
window[var]
You should consider storing all of your factories on an object:
var factories = {
factoryA: { method: function() {} },
factoryB: { method: function() {} },
};
var factory = 'factoryA';
factories[factory].method();
Related
I have one BaseController with common functions which my all other controllers inherit .
The controller is like this
function BaseController () {
this.defaultFilters = {};
this.doStuff = function ($scope) {
$scope.myobj.value = 1;
this.otherfunction();
};
I inherit that in my controller like this
BaseController.call($scope);
Now in my do stuff function i need to pass $scope because myobj is only visible there.
Now i want to know that how can i pass that in my template because i want to call that function when some click on some button
ng-click="doStuff(scope)"
Everything that you associate with your controller's scope, so you just associate your scope with some variable and i guess that will do the job.
Something like this :
app.controller(function($scope) {
$scope.scope = $scope;
});
But if you go by some standard approach, i suggest moving these common functions inside some service, injecting this service into each controller and using it in the views.
Something like this :
app.service("constantService", function() {
this.data = {}; // This will represent your common data.
this.commonFunction = function() {
};
});
app.controller(function() {
$scope.constantService = constantService;
// You can now use $scope.constantService.data as your reference for data, and then can copy it to some local $scope variable whenever required.
});
ng-click="constantService.commonFunction()"
I would like to create a service that will create an interface to AngularJS's $http based on this. I would like to use dependency injection to inject the service without re-writing individual function calls and keeping the code clean. To do this I am providing a common service that creates a variable to the $http object like this:
commonService = function(...) {
return {
...
$http: $http
}
Then I use common.$http everywhere in the code. To change $http from AngularJS $http to my httpService, I need to only change it in one place. httpService looks like this:
function httpService($http, $q, pendingRequests, $interval) {
var get = function(url) {
...
return requestPromise;
};
var service = {
get:get
};
return service;
}
This works for calls to $http.get() but what about calls to $http({method:'get', url:'...'}); ?
Is it possible to provide the () method, which is really httpService()()? Otherwise it would call the AngularJs method httpService().
You can just return a function instead of an object. You can add the properties to your function
function httpService($http, $q, pendingRequests, $interval) {
var get = function(url) {
...
return requestPromise;
};
// Instead of returning an object, return a function
var service = function() {
// do whatever you want here
};
service.get = get;
// Add more properties to service as needed
return service;
}
From my understanding factories are an abstraction over Angular's providers, which allow you to return data with less lines of code. However, providers provide more flexibility in that you can better define the service's functionality. I'm still really confused on how to call a simple function from a provider. Everyone seems to be doing them differently and I cannot get mine to work:
myApp.provider('myProvider', function() {
myVar = true;
$get: function() {
return {
myVar: myVar,
}
},
toggleFalse = function() {
myVar = false;
},
})
myApp.controller('myController', function($scope, myProvider) {
myProvider.toggleFalse();
});
This does not seem to work - and I'm having trouble understanding services in general. It says toggleFalse is not defined. How do you properly define a setter function on an Angular service that can be controlled through a controller?
If you do console.dir(myProvider), you'll see that you are getting the object returned from $get. You need to put the function on the returned object:
$get: function() {
return {
myVar: myVar,
toggleFalse: function() {
myVar = false;
},
}
},
This is a simple question of closure.
If you want every instance to have a unique everything, then store everything inside $get.
If you want the majority of the object to be unique, but have some methods or objects/arrays that every instance shares with each other, then define those in the function closure outside of $get and append them to the object returned from $get.
... ("myProvider", function () {
var sharedValue = 19,
sharedFunction = function () {
sharedValue += 1;
return shared value;
};
return {
$get : function () {
return {
unique : 1,
shared : sharedFunction
};
}
};
This isn't an Angular issue, so much as a core piece of JS's behaviour, which happens to be inside of an Angular paradigm.
how can I create a helper/utility class that can be accessible from the multiple controllers?
For example, I have two controllers: UpdateItemCtrl and CreateItemCtrl. These have common functions inside which increases redundancy and lowers managability.
I'd like to create a ItemSaveHelper class which I would put the common methods inside and call them from the active controller.
You want to create a service.
A service is just a singleton that can be injected into different things to provide modular/shared functionality. Here's a simple example: http://jsfiddle.net/andytjoslin/pHV4k/
function Ctrl1($scope, itemManager) {
$scope.addItem = function(text) {
itemManager.items.push(text);
};
}
function Ctrl2($scope, itemManager) {
$scope.items = itemManager.items;
}
app.factory('itemManager', function() {
return {
items: []
};
});
In my application,I have to build a standalone lib for other people use,so I create new object like this:
function MyService(){
//xxxxxxx...
}
MyService.prototype.login=function(name,pass){
//here
}
MyService.prototype.LoadDataFromServer(){
//use the ajax get data from server,when get the data,I will eval them :
var data=parseData(request.responseText);
//now,the parseData is a private method which should not be exposed to the user,but it need the reference of the MyService object(this),so I have to use the following code:
var this_ref=this;
function parseData(res){
this_ref.xxxx=.....
}
}
MyService.prototype.parseData=function(res){
this.xxxxx=....
}
This will make the paresData function to the user.
Now,I wonder which is better?
If you want actually private data/methods you should be using closures better.
var MyService = (function() {
// define "private" methods
var _login = function(name, pass) {
...
},
_loadDataFromServer = function() {
....
},
_parseData = function(res) {
...
};
//return "public" methods
return {
login: _login,
loadDataFromServer: _loadDataFromServer
};
}()); // execute function immediately
MyService now only has the two "public" functions, login and loadDataFromServer you can still access the "private" functions from the public functions but you cannot directly access any of the "private" methods MyService._login('test','pass'); will fail but MyService.login('test','pass'); will work. See this example http://jsfiddle.net/EXrDW/
There is no "better" answer, only what you feel more comfortable with. What a lot of people seem to have adopted is the practice of putting underscores in front of methods that shouldn't be accessed by users.