【问题标题】:How do you call a function from within the factory using a string in angularjs如何使用 angularjs 中的字符串从工厂内部调用函数
【发布时间】:2014-01-08 15:24:59
【问题描述】:

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

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

【问题讨论】:

  • 你只是想返回 someData.amount 吗?
  • 有什么方法可以生成代码,而不是将函数定义为 function foo() {} 而是定义为 this.foo = function () {}?
  • 我应该更清楚。代码是用户定义的,因此我无法控制编写方式/内容。

标签: javascript angularjs angularjs-service angularjs-factory


【解决方案1】:

试试这个方法:

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

【讨论】:

  • 是的。这会起作用,但需要我强制执行有关如何编写代码的规则。我真的不想那样做。
【解决方案2】:

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

【讨论】:

  • 我也不喜欢 -1 先生,但在 JS 中没有任何方法可以将 foo 函数作为字符串调用。由于这个事实,我不得不改变我的方法,但我很想被证明是错误的。
【解决方案3】:

您可以使用 $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>

【讨论】:

  • 这将要求最终用户创建一个 internalFunctions obj。并在他们修改代码时保持最新。我试图阻止用户关心环境。我希望有一个我不知道的鬼鬼祟祟的 JS 技巧。不过谢谢。 :)
猜你喜欢
  • 2014-11-27
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-20
  • 1970-01-01
  • 2014-04-25
相关资源
最近更新 更多