2008-09-17 5 views
7

Par exemple, je veux pouvoir programmer une ligne de code comme suit où le nom de la fonction est assigné dynamiquement sans utiliser Evaluate(). Le code ci-dessous ne fonctionne bien sûr pas mais représente ce que j'aimerais faire.Comment faire pour appeler une fonction dynamiquement qui fait partie d'un cfc instancié, sans utiliser Evaluate()?

application.obj[funcName](argumentCollection=params) 

La seule façon que je peux trouver pour appeler une fonction est dynamiquement à l'aide cfinvoke, mais pour autant que je peux dire que instancie le cfc/fonction liée à la volée et ne peut pas utiliser un cfc précédemment instanciée.

Merci

+1

Juste pour compléter l'image, Railo 3.3 prend en charge la syntaxe désirée. Et j'aime ça. – Sergii

+1

Vous pouvez voter pour Adobe pour soutenir cette syntaxe dans CF ici: [Bug 82579] (http://cfbugs.adobe.com/cfbugreport/flexbugui/cfbugtracker/main.html?#bugId=82579) –

Répondre

9

Selon la documentation, vous pouvez faire quelque chose comme ceci:

<!--- Create the component instance. ---> 
<cfobject component="tellTime2" name="tellTimeObj"> 
<!--- Invoke the methods. ---> 
<cfinvoke component="#tellTimeObj#" method="getLocalTime" returnvariable="localTime"> 
<cfinvoke component="#tellTimeObj#" method="getUTCTime" returnvariable="UTCTime"> 

Vous devriez être en mesure d'appeler simplement avec méthode = « # myMethod # » pour appeler dynamiquement une fonction particulière .

+0

J'ai essayé différentes combinaisons pour cfinvoke mais en quelque sorte négligé cela. Merci –

+0

C'est la méthode la plus rapide. –

+0

:) sympa. Je ne savais pas que tu pouvais le faire, mais c'est très pratique. – jinglesthula

4

Vous pouvez utiliser cfinvoke. Vous n'êtes pas obligé de spécifier un composant.

<cfinvoke method="application.#funcName#" argumentCollection="#params#"> 
1

Vous pouvez également faire quelque chose de très similaire à la façon dont vous vouliez l'utiliser. Vous pouvez accéder à la méthode dans l'objet en utilisant la syntaxe que vous avez utilisée, vous ne pouvez pas l'appeler en même temps. Cependant, si vous attribuez à une variable temporaire, vous pouvez l'appeler

<!--- get the component (has methods 'sayHi' and a method 'sayHello') ---> 
<cfset myObj = createObject("component", "test_object")> 

<!--- set the function that we want dynamically then call it (it's a two step process) ---> 
<cfset func = "sayHi"> 
<cfset funcInstance = myObj[func]> 
<cfoutput>#funcInstance("Dave")#</cfoutput> 

<cfset func = "sayHello"> 
<cfset funcInstance = myObj[func]> 
<cfoutput>#funcInstance("Dave")#</cfoutput> 
+0

La copie de la fonction depuis myObj dans la page ou un autre CFC peut avoir un impact négatif si la fonction utilise des variables de portée 'this' ou 'variables'. –

1

En CFML, les fonctions sont membres de première classe de la langue. Cela nous permet de les faire circuler comme une variable. Dans l'exemple suivant, je vais copier la fonction nommée 'foobar' et la renommer "$ fn" dans le même objet. Ensuite, nous pouvons simplement appeler $ fn().

funcName = 'foobar';  
application.obj.$fn = application.obj[funcName]; 
application.obj.$fn(argumentCollection=arguments); 

Le contexte de la fonction est importante, surtout si elle fait référence à des valeurs dans les « variables » ou « cette » portée de l'objet. Note: ceci n'est pas sûr pour les instances CFC dans les étendues partagées!

La méthode la plus rapide consiste à utiliser la recommandation de Ben Doom. Je voulais juste être complet.

+0

c'est un bon point Aaron. Oui, si vous avez besoin de conserver le contexte (ce que vous feriez généralement dans un vrai style OO), la copie de la fonction hors de la portée du composant échouera. –

+0

Alors que la conversation se déplaçait vers Twitter, @seancorfield a souligné que ce ne sera pas thread sur un singleton. Si plusieurs threads peuvent appeler le même $ fn, le mieux est de randomiser le nom. BTW Cette méthode semble être aussi rapide que eval ("application.obj. # FuncName # (argumentCollection = arguments)"); –

Questions connexes