3

更新: railoにはこの問題はまったくないようです。

更新:人々がこの質問の「大きなコンポーネントを分割するより良いアイデアを持っていますか」という部分(私が決して入れるべきではなかった)全体にもっと焦点を合わせていると感じているので、私はこの問題を閉じることに投票していますcfcomponent で cfincludes を使用する方法。

注:これは、アイデアを理解するために私がやろうとしていることの単純化された例です。

私が抱えている問題は、cfcomponent 内で cfinclude を使用して、同様のメソッドを別のファイルにグループ化し、管理しやすくしたいということです。私が直面している問題は、以下に示すように、cfinclude を使用してそのメソッドを管理する別のコンポーネントを拡張しようとしたときです。ComponentA は ComponentB を拡張することに注意してください。

ComponentA
==========
<cfcomponent output="false" extends="componentb">
    <cfinclude template="componenta/methods.cfm">
</cfcomponent>

componenta/methods.cfm
======================
<cffunction name="a"><cfreturn "componenta-a"></cffunction>
<cffunction name="b"><cfreturn "componenta-b"></cffunction>
<cffunction name="c"><cfreturn "componenta-c"></cffunction>
<cffunction name="d"><cfreturn super.a()></cffunction>

ComponentB
==========
<cfcomponent output="false">
    <cfinclude template="componentb/methods.cfm">
</cfcomponent>

componentb/methods.cfm
======================
<cffunction name="a"><cfreturn "componentb-a"></cffunction>
<cffunction name="b"><cfreturn "componentb-b"></cffunction>
<cffunction name="c"><cfreturn "componentb-c"></cffunction>

問題は、ComponentA を初期化しようとすると、「ルーチンを複数回宣言することはできません。ルーチン a が異なるテンプレートで 2 回宣言されています」というエラーが表示されることです。

これの全体的な理由は、cfinclude を使用すると、COMPILE TIME ではなく RUN TIME で評価されるためです。

メソッドをコンポーネント自体に移動し、cfinclude の使用を排除する以外に、どうすればこれを回避できますか、または誰かが大きなコンポーネントを分割するより良いアイデアを持っていますか?

4

5 に答える 5

2

テストされていませんが、各関数の内容をインクルードに入れてみますが、コンポーネント ファイル自体の中で関数を定義します。`

<cfcomponent name="a">
    <cffunction name="aa">
        <cfinclude template="componenta/functiona.cfm" />
    </cffunction>
</cfcomponent>

幸運を。

于 2010-06-13T03:22:34.690 に答える
0

これについてはzarkoと一緒です。オブジェクトを再配置する必要がありますが、必要な場合は...

CF5 では、関数をリクエスト スコープに入れるというトリックを使用しました。これは、関数名を同じ名前のリクエスト変数に割り当てることで実行できます。つまり、getLatestUpdate という関数の場合です。

Request.getLatestUpdate = getLatestUpdate

次に、関数を含むファイルを含める前に、リクエストスコープに変数が存在するかどうかを確認します。リクエスト スコープ変数が存在しない場合にのみ、関数ファイルを cfinclude します。

欠点は、リクエスト スコープ プレフィックスを使用して関数を参照する必要があることです。また、これはページ リクエストの従来の比喩でのみ機能し、リモート呼び出しなどで中断する可能性が高くなります。

これと YMMV はテストしていません。

于 2010-06-12T22:49:46.010 に答える
0

問題が純粋に巨大で扱いにくいオブジェクトを回避することである場合は、オブジェクトをいくつかの小さなオブジェクトに分割できます。コンポーネント A には引き続きメソッド ABCD を含めることができますが、メソッド A は ComponentA_A メソッド A を呼び出し、メソッド B は ComponentA_B メソッド B を呼び出すなどです。実験すべきもう 1 つのこと (これは暗黒面での突っ込みです) 関数は、通常、何らかのスコープに接続された構造として記述されます。たとえば、structDelete(this, onRequestStart) によって Application.cfc から関数を削除できます。同じアプローチを使用して、以前にインクルードのリクエスト スコープにアタッチされていた関数を削除できますか?

于 2010-06-14T03:57:26.980 に答える
0

私のアドバイスは、オブジェクトを再分析し、すべての OOP ルールとベスト プラクティス (抽象化、カプセル化、モジュール性、ポリモーフィズム、継承、DRY など) に適用するようにしてください。

したがって、基本的には、コンポーネント B にメソッド isCrunchable() を持たせ、コンポーネント A が B を拡張し、継承から isCrunchable() を利用できるようにする必要があります。A と B の両方が異なる状態を返すので、これで問題はないと思います。すべてのメソッドとコンポーネント A および B がそのクラスを拡張する「上」の 1 つのクラスを作成すると、「大きなコンポーネント」のソリューションが得られますが、もう一度、これをもう少しクランチしようとします。

この回答が役に立たない場合は、実際の例を投稿できます.

于 2010-06-12T21:17:05.010 に答える
0

私はそれをテストしていませんが、次のようなもので cfinclude をラップするのはどうですか:

<cfif NOT structKeyExists(this,"someMethodNameInIncludeFile")>
      <cfinclude....>
</cfif>
于 2010-06-12T23:52:15.633 に答える