如何使用angularjs中的字符串从工厂内调用函数

时间:2013-12-19 21:40:16

标签: javascript angularjs angularjs-service angularjs-factory

我有一些逻辑我想要包装到AngularJS工厂,所以我可以使用angular的依赖注入。由于逻辑是动态的,我不一定知道提前调用什么。我所拥有的是一个字符串,表示要调用的函数的名称。我知道我可以做window["someFunctionName"]()之类的东西来运行一个带字符串的函数,但由于所有东西都包含在工厂中,我不知道如何引用工厂来调用它。恩。 sampleFactory["someFuncitonName"]();

我发现运行该功能的唯一方法是使用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]();?有没有更好的方法来做到这一点?谢谢你的帮助。

更新:由于评论中的代码是用户定义的,我无法知道也无法控制评论中的代码是如何编写的。我不想强迫用户施加任何限制。因此,我可以期待很少。

3 个答案:

答案 0 :(得分: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");
    }
}

答案 1 :(得分: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>

答案 2 :(得分:-1)

从我读过的内容来看,没有办法做到这一点。它只是javascript如何工作。无法通过字符串调用foo函数。 foo函数必须是用字符串调用它的对象的一部分。我只想确认没有任何聪明的方法。