2

我有一些逻辑我想要包装到AngularJS工厂中,以便我可以使用angular的依赖注入。由于逻辑是动态的,我不一定知道什么可以提前打电话。我所拥有的是一个表示要调用的函数名称的字符串。我知道我可以像window["someFunctionName"]()那样使用字符串运行函数,但是因为所有内容都被封装在工厂中,所以我不知道如何获取工厂的参考来调用它。恩。 sampleFactory["someFuncitonName"]();如何在工厂内使用angularjs中的字符串调用函数

我发现运行该功能的唯一方法是使用eval("someFuncitonName()")。很显然,如果可以的话,我想避免使用eval。

这里是什么,我试图做一个例子:

'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](); 
     } 
    }; 

    }); 

在控制器中的用户将运行像这样testFactory.funcRunner("foo");

有什么办法可以沿着这些路线做点什么testFactory[functionName]();?有没有更好的方法来做到这一点?谢谢你的帮助。

更新:由于评论中的代码是用户定义的,我无法知道,也无法控制评论中代码的写入方式。我不想强制用户有任何限制。所以我可以期待很少。

+0

你只是想要返回someData.amount? –

+1

有什么办法可以生成代码,而不是将函数定义为函数foo(){},它被定义为this.foo = function(){}? – drdalton

+0

我应该更清楚。代码是用户定义的,所以我不能控制如何/写什么。 – yodaisgreen

回答

-1

从我看过没有办法做到这一点。它只是如何JavaScript的作品。没有办法通过字符串调用foo函数。 foo函数必须是用字符串调用它的对象的一部分。我只是想确认有没有什么聪明的方法。

+1

我不喜欢它先生-1,但没有任何方法可以将JS函数作为字符串调用。由于这个事实,我不得不改变我的方法,但我希望被证明是错误的。 – yodaisgreen

5

试试这个办法:

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"); 
    } 
} 
+0

是的。这将工作,但会要求我执行如何编写代码的规则。我真的不想那么做。 – yodaisgreen

0

您可以使用$ parse来解析字符串并调用函数。这里有一个例子: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!'); 
    } 
} 

下面是一些简单的标记,使该buttonClick和传递的字符串中。

<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> 
+0

这将要求最终用户创建一个internalFunctions obj。并在修改代码时保持最新状态。我试图阻止用户不必关心环境。我希望有一个我不知道的鬼祟的JS技巧。不过谢谢。 :) – yodaisgreen

相关问题