所以,鉴于我有一个这个组件的实例:
foo.cfc
<cfcomponent>
<cffunction name="locateMe">
<cfreturn "I don't know where I live!">
</cffunction>
</cfcomponent>
而且,这个其他组件,fooParent.cfc:
<cfcomponent>
<cfset this.foo = createObject("component", "foo")>
</cfcomponent>
假设我用几种不同的方式创建“foo”实例:
<cfset myStruct = {}>
<cfset myStruct.foo = createObject("component", "foo")>
<cfset myFoo = createObject("component", "foo")>
<cfset myFooParent = createObject("component", "fooParent")>
<cfoutput>
#myStruct.foo.locateMe()#<br>
#myFoo.locateMe()#<br>
#myFooParent.foo.locateMe()#<br>
</cfoutput>
正如预期的那样,输出:
I don't know where I live!
I don't know where I live!
I don't know where I live!
我想知道的是,我可以在foo.cfc中做些什么来告诉我关于它被调用的上下文的内容(任何事情!)?因为一切最终都存在于(至少)某种范围内,并且所有范围都是一种对象,我所说的是我真的想要某种方式来确定包含对象,从给定内部实例化对象。最终,从上面的示例代码段构建foo.cfc以便这样的东西可以作为我的输出的一些方法:
I live within a "class coldfusion.runtime.Struct" instance!
I live within a "class coldfusion.runtime.VariableScope" instance!
I live within a "component cfjunk.fooParent" instance!
其中每个值都可以通过检查传递getMetaData
实际包含对象引用的结果来确定。
更新正如Micah在评论中所建议的,我已经添加了“Java”标签,因为我怀疑他可能是正确的,因为解决方案可能在于使用Java进行内省。
更新
让我解释为什么我需要这个,而不是将其视为纯粹的学术讨论。
我正在使用带有包含的CFWheels ORM来获取对我的数据的引用,如下所示:
var user = model("User").findOne(where="id=123", include="AuthSource", returnAs="object");
这将返回给我一个我可以这样引用的对象:
user.id // property of the "User" model
user.reset() // method on the "User" model
user.AuthSource.id // property of the "AuthSource" model
user.AuthSource.authenticate(password) // method on the "AuthSource" model
现在,在我的“AuthSource.authenticate”方法中,我想知道我所包含的“用户”对象。否则,我最终将不得不调用这个函数,而不是:
user.AuthSource.authenticate(user, password) // note the redundancy in the use of "user"
我应该能够依赖这样一个事实,即我通过User对象在AuthSource模型上调用该方法,并实际从该方法中读取该对象。
答案 0 :(得分:4)
自从我完成了coldfusion以来已经很长时间了,所以请原谅我的伪代码,但我认为在这些实例中通常做的是让父母将它自己的副本发送给孩子,当它实例化时孩子这用于许多OOP设计模式,其中两个对象需要以两种方式相互通信,而不仅仅是孩子的父调用方法。
因此您的子课程将被定义为:
<cfcomponent>
<cffunction name="init">
<cfargument name="parentParam" required="yes" type="object">
<cfset this.parent = parentParam >
<cfreturn this>
</cffuncton>
<cffunction name="locateMe">
<cfreturn "I belong to #this.parent.className# !">
</cffunction>
<cffunction name="doOtherStuff">
<cfreturn "I do stuff with my parent: #this.parent.className# !">
</cffunction>
</cfcomponent>
然后当你使用它时......
<cfset myParent.child = createObject("component", "Object").init(myParent) />
#myparent.locateMe()#
#myparent.doOtherStuff()#
parentParam将是名为“init”的构造函数方法中的必需参数,因此子节点始终具有对其父节点的引用。然后你所有的方法都可以利用this.parent来做它的东西。在我的代码示例中,我做#this.parent.className#但不知道coldfusion对象有这样的属性。也许你可以使用某种反射或元编程来做同样的事情。
请注意:从我收集到的内容来看,coldfusion不支持内置的构造函数,因此我向您展示了来自此站点的社区标准最佳实践:
我很遗憾你正在做斗式......;)
答案 1 :(得分:0)
我删除了之前的所有内容,因为它似乎没有帮助。在您稍后的评论之后,以下是我认为可能更符合您的目标的建议。
// Object
<cfcomponent displayname="Object">
<cffunction name="init">
<cfargument name="username" type="string">
<cfscript>
variables.username = arguments.username;
variables.authSource = CreateObject('component','AuthSource').init();
</cfscript>
<cfreturn this>
</cffunction>
<cffunction name="authenticate">
<cfargument name="password" type="string">
<cfreturn variables.authSource.authenticate(variables.username,arguments.password)>
</cffunction>
</cfcomponent>
<cfcomponent displayname="AuthSource">
<cffunction name="init">
<cfreturn this>
</cffunction>
<cffunction name="authenticate">
<cfargument name="username" type="string">
<cfargument name="password" type="string">
.... DO STUFF ...
<cfreturn ...>
</cffunction>
</cfcomponent>
<cfscript>
objUser = CreateObject('component','Object').init('SomeUserName');
// Authenticate
objUser.authenticate('SomePassword');
</cfscript>
这样,AuthSource不需要知道父对象,但同时有人进行身份验证不需要再次传入用户名。 Object(父对象)有一个用于身份验证的包装方法,用于添加用户名。
这有任何进一步的帮助吗?
答案 2 :(得分:0)
我知道这现在不相关,但CF的下一个版本(Zeus)有一个功能http://blogs.adobe.com/coldfusion/2011/12/19/coldfusion-zeus-potr-callstack/。