4

背景

我正在尝试创建一个componentFromJson可以从 JSON 重构组件图的函数。我采用了一种简单的方法getMetaData来查找组件属性以实例化正确的类型。

该函数将像这样使用:comp = componentFromJson(json, 'RootComponentType')

问题

问题是属性的类型不一定是完全限定的,因为可能已经导入了命名空间,如下所示。

<cfimport path="some.namespace.Test">

<cfcomponent>
    <cfproperty name="test" type="Test">
</cfcomponent>

当我试图createObject('Test')componentFromJson函数上下文中执行时,它显然失败了,因为调用上下文没有导入。

我尝试了很多不同的方法来解决这个问题,包括在父组件上临时动态定义组件工厂函数,以及invoke在父CFC的上下文中使用调用工厂函数,但它不起作用。

例如

<cfscript>
    parentCmp = createObject('SomeCmp');
    parentCmp.createComponent = function (type) {
        return createObject(type);
    };
    childCmp = invoke(parentCmp, 'createComponent', { type = 'Test' });
</cfscript>

可怕的解决方案

我现在能想到的解决这个问题的唯一方法是解析 CFC 的 ColdFusion 代码并提取导入语句,但我预计这对于目的来说太慢了。不仅如此,而且这不会涵盖所有边缘情况。

想法?

我想知道是否有人有更好的想法来解决这个问题?我可以采取完全不同的方法吗?可能有一种方法可以使用 ColdFusion 运行时类来做到这一点,但我还没有弄清楚。

4

1 回答 1

1

好吧,事实证明,当您了解 ColdFusion 运行时的底层机制(最初我很难找到)时,这并不难。

我终于发现了一个以 a 表示的 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')>
于 2016-08-24T22:28:56.780 回答