2

我有一些逻辑想包装到 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]();?有没有更好的方法来做到这一点?谢谢你的帮助。

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

4

3 回答 3

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");
    }
}
于 2013-12-20T00:22:43.673 回答
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>
于 2014-09-09T00:17:54.323 回答
-1

根据我的阅读,没有办法做到这一点。它就是 javascript 的工作原理。无法通过字符串调用 foo 函数。foo 函数必须是对象的一部分才能用字符串调用它。我只是想确认没有任何聪明的方法可以解决这个问题。

于 2014-01-02T03:18:41.600 回答