1

DAO機能を持つBeanである2つのCFCがあります。子 cfc が親を拡張する継承を設定しました。

両方のオブジェクトの構造は同じです。関数: init、read などおよびプロパティ: ID など

子オブジェクトを作成するときに ID を渡します。ID はデータを読み取り、親の外部キーの parentID を取得し、適切なパラメーターを指定して Super.init() を呼び出します。

私の予期しない結果は次のとおりです。子のIDとparentIDの両方が同じで、オブジェクトが返されたときのparentID値です。childs variables.ID は、super 呼び出しの後に上書きされます。変数スコープは両方からアクセスできると想定しているため、親が変数.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>

4

3 に答える 3

2

オブジェクトを拡張しているため、親と子の両方の変数スコープが共有されるためvariables.id、親は子と同じvariables.idであり、子と親の両方がそこに格納されているものにアクセスまたは上書きできます。

また、extend を使用するreadと、子関数 read が で明示的に呼び出さない限り、親関数が呼び出されることはありませんsuper.read()

また、ORM を使用するようにアプリケーションとコンポーネントをセットアップしていない限り、cfpropertyタグは Web サービスにのみ適しています。

于 2012-10-09T17:05:46.110 に答える
1

まず、garygilbert と KRC の両方が、私を正しい方向に導くのに役立ちました。ありがとうございました。

次の情報を収集しました。子と親の両方が同じ変数スコープを共有するため、スーパーで変数.ID に値を割り当てると、子変数.ID の値が上書きされました。

同様に、子関数の read は、OO 関数の上書きにより、親の read 関数よりも優先されます。

私の調整された解決策: スーパー関数を呼び出す前に、子 ID である一時 ID を設定します。ID を init 関数に渡すと read 関数が自動的に呼び出されるため、親オブジェクトでこれを行うことは避けたかったのです。Super.init(dsn) を呼び出して初期化し、次に Super.setID(ID)、最後に Super.read() を呼び出します。super 呼び出しの後、最初の子 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>
于 2012-10-09T19:17:56.757 に答える
0

これが発生する理由は、CFcfpropertyがCFCの排他的なスコープではなく、オブジェクト全体のVARIABLESスコープの値をスコープする方法(一般的に受け入れられているVARIABLES.instance構造体のプラクティスのように)によるものだと思います。

VARIABLESスコープは、継承された親を含むオブジェクト全体で共有されるため、親と子の両方でID値に名前を付けることで、2つの別々の変数を宣言するのではなく、実際には2回宣言するだけです。次に、IDをに渡すsuper.init()と、子IDのID値が、親Beanに渡したID値に上書きされ、結果が発生します。これを別の方法で動作させたい場合は、親の変数の名前を共有するテスト関数を子に作成してみてください。その変数に値を割り当てsuper.init()、子関数がオブジェクトから消えるのを確認します。

ですから、答えるなら、やりたくないことをしなくても問題を解決できるとは思いません。親IDに別の名前を使用するか、組み込みのアクセサー機能を使用せずにすべてのゲッター関数を手動で記述して、CFC専用のスコープに設定する必要があります。

于 2012-10-09T15:43:37.513 に答える