I'm looking for the best way to dynamically call a method from a different component in cfscript. Notice that it's concerning a method in a different component. So far I've tried 3 different methods, but none of them seem be exactly what I'm looking for:
All cases are written in cfscript inside a component method. Let's say I'm trying to dynamically call the setName(required string name)
method in the MyComponent component. All cases have following variables defined:
var myComp = new MyComponent();
var myMethod = "setName";
var args = {"name"="foo"};
use evaluate()
for the job
evaluate("myComp.#myMethod#(argumentCollection=args)");
pros: is done with very little code
cons: code is not very 'clean' and use of evaluate() seems to have an 'evil' reputation in the online community. I wouldn't want my code to be evil.
use a cfml wrapper for <cfinvoke>
invoke("MyComponent", myMethod, args);
pros: I can use all functionality of cfinvoke
cons: It creates a new instance of MyComponent
with every invoke.
create a dynamicMethod
method in MyComponent
myComp.dynamicMethod(myMethod, args);
dynamicMethod of MyComponent:
public any function dynamicMethod(required string methodName, required struct argumentColl){
var cfcMethod = variables[arguments.methodName];
return cfcMethod(argumentCollection=arguments.argumentColl);
}
pros: I can finally call myComp directly. Most comfortable solution so far.
cons: I can now call private methods of MyComponent via dynamicMethod.
(I've also tried the 'function as variable' solution outside of MyComponent, but then the function looses its working context. e.g. if MyComponent would extend a component, the 'super' scope would no longer refer to the extended component).
None of these solutions seem to be perfect, so is there no other way to call a dynamic function from a different controller?
And if there isn't, which one of these is the best solution?
Any advice is welcome, thanks.
Good analysis.
One thing you could do here is to more-closely emulate <cfinvoke>
with your wrapper function. <cfinvoke>
will take either a component path or a component instance (ie: an object) in that COMPONENT
attribute. So your 'con' of 'It creates a new instance of MyComponent with every invoke.' isn't really valid.
ColdFusion 10, btw, adds a invoke()
function to achieve just this. I note you're on CF9, so this is no help to you. But it's perhaps relevant for other people who might land on this question.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With