继承的CFC没有填充

时间:2012-10-09 14:35:40

标签: inheritance coldfusion cfc

我有两个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>

3 个答案:

答案 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独有的范围内。

相关问题