8

我正在寻找从 cfscript 中的不同组件动态调用方法的最佳方法。请注意,它涉及不同组件中的方法。到目前为止,我已经尝试了 3 种不同的方法,但它们似乎都不是我想要的:

所有的案例都写在一个组件方法中的cfscript中。假设我正在尝试动态调用MyComponent组件setName(required string name)中的方法。所有案例都定义了以下变量:

var myComp = new MyComponent();
var myMethod = "setName";  
var args = {"name"="foo"};
  • 用于evaluate()工作

    evaluate("myComp.#myMethod#(argumentCollection=args)");
    

    优点:用很少的代码完成
    缺点:代码不是很“干净”,并且评估()的使用似乎在在线社区中有一个“邪恶”的名声。我不希望我的代码是邪恶的。

  • 使用 cfml 包装器<cfinvoke>

    invoke("MyComponent", myMethod, args);
    

    优点:我可以使用cfinvoke
    缺点MyComponent的所有功能:每次调用都会创建一个新实例。

  • dynamicMethod在 MyComponent 中 创建一个方法

    myComp.dynamicMethod(myMethod, args);
    

    MyComponent 的动态方法:

    public any function dynamicMethod(required string methodName, required struct argumentColl){  
      var cfcMethod = variables[arguments.methodName];  
      return cfcMethod(argumentCollection=arguments.argumentColl);
    }
    

    优点:我终于可以直接调用 myComp 了。迄今为止最舒适的解决方案。
    缺点:我现在可以通过 dynamicMethod 调用 MyComponent 的私有方法。
    (我还在 MyComponent 之外尝试了“作为变量的函数”解决方案,但随后该函数失去了它的工作上下文。例如,如果 MyComponent 将扩展一个组件,则“超级”范围将不再引用扩展的组件)。

这些解决方案似乎都不是完美的,所以没有其他方法可以从不同的控制器调用动态函数吗?
如果没有,其中哪一个是最好的解决方案?

欢迎任何建议,谢谢。

4

1 回答 1

7

好分析。

您可以在这里做的一件事是更密切地模拟<cfinvoke>您的包装函数。 <cfinvoke>将在该属性中采用组件路径组件实例(即:对象) 。COMPONENT所以你的“骗局”是“每次调用都会创建一个 MyComponent 的新实例”。不是真的有效。

顺便说一句,ColdFusion 10 添加了一个invoke()功能来实现这一点。我注意到你在 CF9 上,所以这对你没有帮助。但这可能与可能涉及此问题的其他人有关。

于 2012-10-24T10:17:56.657 回答