如何使用cfc对象的引用从另一个函数调用函数?

时间:2014-12-12 10:48:17

标签: coldfusion coldfusion-9 cfwheels

对于问题短语感到抱歉。我无法找到更好的方式来描述它。但我的问题如下:

我有3个cfc,即settings.cfc,prices.cfc和helpers.cfc。这些cfc扩展了第四个cfc controller.cfc。 helper.cfc如下:

<cfcomponent extends="Controller">
    <cffunction name="formatCurrency">
        <cfset formattedCurrency = 1 />    
        <cfreturn formattedCurrency>        
    </cffunction>
    <cffunction name="processTemplateVariables">
       <cfargument name="templateText" default="defaultText" >
       <cfset formatCurrency() />
       <cfreturn formattedCurrency >        
    </cffunction>
</cfcomponent>

settings.cfc有一个 setApplicationVariables 方法,我们用它来设置应用程序级变量。在这个cfc中,我创建了一个helpers.cfc对象,并将该对象放入应用程序范围。 settings.cfc如下:

<cfcomponent extends="Controller">
   <cffunction name="setApplicationVariables">    
      <cfset application.helpers = createObject("component","controllers.Helpers") />  
   </cffunction>
</cfcomponent>

在应用程序启动时调用settings.cfc,然后创建helpers.cfc的对象并将其放入应用程序范围。

我们在controller.cfc中创建对ProcessTemplateVariables方法的引用,如下所示:

<cfcomponent extends="Wheels">
   <cfset getFormattedCurrency = application.helpers.processTemplateVariables >
</cfcomponent>

在prices.cfc中,我们使用此引用来调用function processTemplateVariables。但是它从processTemplateVariables内部调用does not call the function formatCurrency并且它抛出错误&#34; 变量formatCurrency未定义&#34;。

但如果我使用application.helpers.processTemplateVariables(templateText="someText"),它就可以了 当我使用cfinvoke时,它也可以工作:

<cfinvoke method="processTemplateVariables" component="controllers.helpers" templateText="someText" returnvariable="content">

price.cfc如下:

<cfcomponent extends="Controller">
    <cffunction name="index">
        <!--- does not work, throws 'the formatCurrency() variable is undefined' --->
        <cfdump var="#getFormattedCurrency("someText")#"><cfabort>
        <!--- works --->    
        <cfinvoke method="processTemplateVariables" component="controllers.helpers" templateText="someText" returnvariable="content">
        <!--- works --->
        <cfset application.helpers.processTemplateVariables("someText") />   
    </cffunction>
</cfcomponent>

我不确定为什么使用引用不起作用。 对于早先的混乱感到抱歉,但你的评论让我深入挖掘,我发现这是参考,这是罪魁祸首。有没有办法让这个工作参考,那会很酷吗?

2 个答案:

答案 0 :(得分:2)

更新:

This blog entry (by Adam Cameron)有更好的描述。总结一下:

  

..它将方法拉出CFC,因此它将在中运行   调用代码的上下文,而不是CFC实例。取决于   方法中的代码,这可能也可能不重要。

在您的具体情况下,它确实很重要。该函数依赖于formatCurrency,它不存在于&#34; context&#34;调用页面,这就是为什么你得到一个&#34; undefined&#34;错误。


(来自评论)

是的,我很确定你不能这样做。每个函数都编译成一个单独的类:specifically a static inner class。 (如果转出不带括号的函数名称即#application.helpers.formatCurrency#,则可以看到内部类名。)换句话说,它与任何特定实例(以及扩展名) - 其他函数断开连接。

创建组件的实例时,所有函数都存储在variables范围内。所以当你调用&#34; processTemplateVariables&#34; - 来自实例中的 - 它可以通过组件的variables范围访问其他功能。当您的代码创建对该函数的引用时,您实际获得的内容与父实例application.helpers完全断开连接。因此它无法访问任何其他功能。因此,为什么你得到一个&#34; undefined&#34;错误。

答案 1 :(得分:1)

Leigh的答案可以很好地理解这种限制。

在这里关注你的要求:使用函数的短名称别名,你仍然可以使用原始代码,添加所有相关函数作为参考,以便它们在{{{ 1}}范围类似于controller.cfc

编辑1:

getFormattedCurrency

现在,对于有趣的部分,很有可能从另一个cfc访问一个函数并仍保留所有依赖项。当我回忆起 Bennadel here的惊人帖子时,我也很惊讶。这简直太神奇了。但要警告你这种做法是不鼓励的。所以我接受了你的设置并继续前进。这一切都像一个魅力,到目前为止没有遇到任何问题(但我很确定可能会出现一些并发症)。 原始用法的问题在于该函数依赖于 formatCurrency ,这在&#34; context&#34;中不存在。在他的回答中由Leigh教育的调用页面。 那么如果您只是将范围内的对象甚至是其他组件中的函数复制到<cfcomponent extends="Wheels"> <cfset getFormattedCurrency = application.helpers.processTemplateVariables /> <cfset formatCurrency = application.helpers.formatCurrency /> </cfcomponent> ,怎么办呢,同时听起来很奇怪和惊人,但是可以使用控制器内的controller.cfc标签.cfc(注意:不鼓励)基于 Bennadel 用于他的例子的想法。

EDIT2:

你的controller.cfc应该是这样的:

<cfinclude>

请注意,您现在甚至不需要为这些功能创建简写别名。所有组件和视图都可以按预期直接使用函数名称。 如果扩展 Controller.cfc 的任何其他组件具有相同名称的函数,则无需指出 命名冲突 的可能性作为正在导入的组件库中的任何函数。但是这些可以通过将函数更专业化为多个组件来解决,或者像使用前缀作为函数名称的编码标准的一部分一样简单,以避免任何此类未来场景。