from what I have read there isn't a way to do this. Its just how javascript works. There is no way to call the foo function via a string. The foo function would have to be part of an object to call it with a string. I just wanted to confirm there aren't any clever ways around this.
How do you call a function from within the factory using a string in angularjs
-
19-09-2022 - |
Pregunta
I have some logic I would like to wrap up into an AngularJS factory so I can use angular's dependency injection. Since the logic is dynamic I don't necessarily know what is available to call ahead of time. What I have is a string representing the name of the function to call. I know I can do something like window["someFunctionName"]()
to run a function with a string but since everything is wrapped up in a factory I'm not sure how to get reference to the factory to call it. ex. sampleFactory["someFuncitonName"]();
The only way I have found to run the function is using eval("someFuncitonName()")
. Obviously I would like to avoid using eval if I can.
Here is an example of what I'm trying to do:
'use strict';
angular.module('testApp')
.factory('testFactory', function (someData) {
// User defined code that was wrapped up in a factory
function foo() {
someData.amount = 5;
}
// End dynamic code
return {
funcRunner: function(functionName) {
testFactory[functionName]();
}
};
});
In the controller the user would run something like this testFactory.funcRunner("foo");
.
Is there some way to do something along these lines testFactory[functionName]();
? Is there some better way of doing this? Thanks for your help.
Update: Since the code in the comment is user defined I have no way of knowing nor do I have any control over how the code in the comments is written. I don't want to force any restrictions on the user. Therefore I can expect very little.
Solución 3
Otros consejos
Try this approach:
angular.module('testApp').factory('testFactory', function () {
var service = this;
this.foo = function() {
someData.amount = 5;
}
return {
funcRunner: function (functionName) {
service[functionName]();
}
};
});
function Ctrl($scope, testFactory) {
$scope.click = function () {
testFactory.funcRunner("foo");
}
}
You can use the $parse to parse the string and call a function. Here's an example: http://jsfiddle.net/WeirdAlfred/Lsfwtb96/
var app = angular.module('myApp', []);
//inject the $parse service into your controller, service, factory, etc.
app.controller('myController', ['$scope', '$parse', myController]);
function myController($scope, $parse) {
//setup a function on scope that will receive the
//string that you wish to execute as a function.
//Note: this function doesn't need to be on scope, it's just there so
//we can call it with button clicks. This could be any function
//on a controller, service, factory, etc.
$scope.buttonClick = function (someStringValue, useAngularParse) {
alert('The string value passed in from the button click: ' + someStringValue);
//the parse service takes a string and converts it to a function call
//the format for the command is:
//$parse(inputString)(objectOfAvailableFunctions, objectOfParams);
$parse(someStringValue)(internalFunctions);
}
//this provides a list of available functions for the
//$parse to call when it evaluates the given string.
var internalFunctions = {
catsSuckEggs: catsSuckEggs,
dogsRock: dogsRock
}
//some random function that you want to make available via a string
function catsSuckEggs() {
alert('My cat is worthless!');
}
//some other random function that you want to make available via a string
function dogsRock() {
alert('I wish my wife would let me have a dog!');
}
}
Here's some quick markup that enables the buttonClick and passes in the string.
<body ng-app="myApp">
<div ng-controller="myController">
<h2>Do you like Cats or Dogs?</h2>
<button class="btn btn-danger" ng-click="buttonClick('catsSuckEggs()')">Cats</button>
<button class="btn btn-success" ng-click="buttonClick('dogsRock()')">Dogs</button>
</div>
</body>