背景
我正在尝试创建一个可以从JSON重构组件图的函数componentFromJson.我采用了一种简单的方法,我使用getMetaData来查找组件属性以实例化正确的类型.
该函数将使用如下:comp = componentFromJson(json,’RootComponentType’)
问题
问题是属性的类型不一定是完全限定的,因为可能已经导入了名称空间,如下所示.
<cfimport path="some.namespace.Test">
<cfcomponent>
<cfproperty name="test" type="Test">
</cfcomponent>
当我尝试从componentFromJson函数上下文执行createObject(‘Test’)时,它显然失败了,因为调用上下文没有导入.
我已经尝试了许多不同的方法来解决问题,包括动态地在父组件上临时定义组件工厂函数,并使用invoke在父CFC的上下文中调用工厂函数,但它不起作用.
例如.
<cfscript>
parentCmp = createObject('SomeCmp');
parentCmp.createComponent = function (type) {
return createObject(type);
};
childCmp = invoke(parentCmp, 'createComponent', { type = 'Test' });
</cfscript>
可怕的解决方案
我现在能想到解决这个问题的唯一方法是解析CFC的ColdFusion代码并提取import语句,但是我觉得这个目的太慢了.不仅如此,但这不会涵盖所有边缘情况.
想法?
我想知道是否有人有更好的想法来解决这个问题?我可以采取完全不同的方法吗?可能有一种方法可以使用ColdFusion运行时类来完成此操作,但我还没有想到它.
最佳答案 好吧,事实证明,当您了解ColdFusion运行时的基础机制(我最初难以找到)时,并不是那么难.
我终于发现一个ColdFusion组件,它表示为coldfusion.runtime.TemplateProxy,它封装了一个coldfusion.runtime.CFPage实例,该实例又有一个createObject方法.
因此,这是我使用Java反射提出的解决方案:
<cfset host = new SomeComponent()>
<cfset pageField = createObject('java', 'coldfusion.runtime.TemplateProxy').getClass().getDeclaredField('page')>
<cfset pageField.setAccessible(true)>
<cfset page = pageField.get(host)>
<cfset test = page.createObject('Test')>