我有两个CFC,它们是具有DAO功能的Beans。我已经设置了子cfc扩展父级的继承。
两个物体具有相同的结构;功能:初始化,读取等,属性:ID等。
当我创建子对象时,我传递一个ID,它读取数据,获取父对象的外键parentID,然后使用适当的参数调用Super.init()。
我意想不到的结果是: 子ID和parentID都是相同的,并且是返回对象时的parentID值。超级调用后会覆盖childs variables.ID。我假设变量范围可由两者访问,因此当父设置variables.ID时,它会覆盖子变量.ID。如果不以不同的方式命名ID,是否可以避免这种情况?
父对象的读取功能似乎不会执行。例如,如果我重命名父项读取函数'read2',则执行该函数。我还怀疑函数驻留在共享范围内,因此子读取函数正在执行。
有没有办法维护相同的cfc结构并使此功能按预期工作?
提前致谢。
<cfcomponent accessors="true" extends="Custom" output="false">
<cfproperty name="ID" type="numeric" />
<cfproperty name="listID" type="numeric" />
<cfproperty name="customfieldID" type="numeric" />
<cfscript>
variables.dsn = '';
</cfscript>
<cffunction name="init" access="public" output="false" returntype="ListCustom">
<cfargument name="dsn" type="string" required="true" />
<cfargument name="ID" type="numeric" required="true" />
<cfargument name="listID" type="numeric" required="false" default="0" />
<cfargument name="customFieldID" type="numeric" required="false" default="0" />
<cfscript>
variables.dsn = arguments.dsn;
variables.ID = arguments.ID;
variables.listID = arguments.listID;
variables.customFieldID = arguments.customFieldID;
if (variables.ID){
read();
if (variables.customFieldID){
Super.init(dsn=variables.dsn,ID=variables.customfieldID);
}
}
</cfscript>
<cfreturn this />
</cffunction>
<cffunction name="read" access="private" output="false" returntype="void">
<cfquery name="local.q" datasource="#variables.dsn#">
SELECT customfieldID, listID
FROM listCustomFields
WHERE ID = <cfqueryparam value="#variables.ID#" cfsqltype="cf_sql_integer">
</cfquery>
<cfif local.q.recordcount>
<cfset variables.listID = local.q.listID />
<cfset variables.customFieldID = local.q.customFieldID />
</cfif>
</cffunction>
<cfcomponent accessors="true" output="false">
<cfproperty name="ID" type="numeric" />
<cfproperty name="fieldName" type="string" />
<cfscript>
variables.dsn = '';
</cfscript>
<cffunction name="init" access="public" output="false" returntype="Custom">
<cfargument name="dsn" type="string" required="true" />
<cfargument name="ID" type="numeric" required="true" />
<cfargument name="fieldName" type="string" required="false" default="" />
<cfscript>
variables.dsn = arguments.dsn;
variables.ID = arguments.ID;
variables.fieldName = arguments.fieldName;
if (variables.ID){
read();
}
</cfscript>
<cfreturn this />
</cffunction>
<cffunction name="read" access="private" output="false" returntype="void">
<cfquery name="local.q" datasource="#variables.dsn#">
SELECT fieldName
FROM CustomField
WHERE ID = <cfqueryparam value="#variables.ID#" cfsqltype="cf_sql_integer">
</cfquery>
<cfif local.q.recordcount>
<cfset variables.fieldName = local.q.fieldName />
</cfif>
</cffunction>
答案 0 :(得分:2)
由于您正在扩展对象,因此共享父项和子项的变量范围,因此父项中的variables.id
与子项中的variables.id
相同,并且子项和父项都可以访问或覆盖那里存储的内容。
除了扩展之外,父函数read
将永远不会被调用,除非子函数读取显式地使用super.read()
调用它。
除非您已将应用程序和组件设置为使用ORM,否则cfproperty
标记仅适用于Web服务。
答案 1 :(得分:1)
首先,garygilbert和KRC都有助于指出我正确的方向。谢谢。
我收集了以下信息: child和parent都将共享相同的变量作用域,因此在super中为variables.ID赋值时,子values.ID值被覆盖。
类似地,由于OO函数被覆盖,子函数读取优先于父读取函数。
我的调整后的解决方案: 在调用超级函数之前设置一个临时ID,即子ID。 如果我将ID传递给init函数,则会自动调用read函数,我想避免在父对象中执行此操作,因为它仍然会调用子函数。 我调用Super.init(dsn)进行初始化,然后调用Super.setID(ID),最后调用Super.read()。在超级调用之后,我恢复了初始子ID。
<cfscript>
variables.dsn = arguments.dsn;
variables.ID = arguments.ID;
variables.listID = arguments.listID;
variables.customFieldID = arguments.customFieldID;
if (variables.ID){
read();
if (variables.customFieldID){
variables.tempID = variables.ID;
Super.init(dsn=variables.dsn);
Super.setID(variables.customfieldID);
Super.read();
variables.ID = variables.tempID;
}
}
</cfscript>
答案 2 :(得分:0)
我认为发生这种情况的原因是因为CF范围cfproperty
如何在整个对象的VARIABLES范围内而不是在CFC的独占范围内(如通常接受的VARIABLES.instance结构)实践)。
VARIABLES范围在您的对象之间共享,包括它的继承父级,因此通过在父级和子级中命名ID值,您实际上只是声明它两次而不是声明两个单独的变量。然后,当您将ID传递给super.init()
时,它会将您的ID值覆盖到您的子ID,并将其传递给您传递到父bean的ID值,从而导致您的结果。如果您希望以不同的方式查看此操作,请尝试在您的子项中创建一个测试函数,该函数在父项中共享变量的名称。在super.init()
中为该变量指定一个值,并观察您的子函数从您的对象中消失。
所以回答一下,我认为如果不做一些你不想做的事情,你就无法解决问题。您需要为父ID使用不同的名称,或者不使用内置访问器功能并手动编写所有getter函数,将它们设置在CFC独有的范围内。