对于问题短语感到抱歉。我无法找到更好的方式来描述它。但我的问题如下:
我有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>
我不确定为什么使用引用不起作用。 对于早先的混乱感到抱歉,但你的评论让我深入挖掘,我发现这是参考,这是罪魁祸首。有没有办法让这个工作参考,那会很酷吗?
答案 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
。
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 用于他的例子的想法。
你的controller.cfc应该是这样的:
<cfinclude>
请注意,您现在甚至不需要为这些功能创建简写别名。所有组件和视图都可以按预期直接使用函数名称。 如果扩展 Controller.cfc 的任何其他组件具有相同名称的函数,则无需指出 命名冲突 的可能性作为正在导入的组件库中的任何函数。但是这些可以通过将函数更专业化为多个组件来解决,或者像使用前缀作为函数名称的编码标准的一部分一样简单,以避免任何此类未来场景。