cfajaxproxy

説明

AJAX クライアントで使用する ColdFusion コンポーネントの JavaScript プロキシを作成します。または、コントロール属性値にバインドされる CFC メソッド、JavaScript 関数、または URL のプロキシを作成します。

シンタックス

<cfajaxproxy 
    cfc = "CFC name" 
    jsclassname = "JavaScript proxy class name"> 
OR 
 
<cfajaxproxy 
    bind = "bind expression" 
    onError = "JavaScript function name" 
    onSuccess = "JavaScript function name">
注意: このタグの属性は attributeCollection で指定でき、その値は構造体になります。attributeCollection で構造体の名前を指定し、タグの属性名を構造体のキーとして使用します。

関連項目

DeserializeJSONIsJSONSerializeJSON、『ColdFusion アプリケーションの開発』のUsing Ajax Data and Development Features

履歴

ColdFusion 8: このタグが追加されました。

属性

属性

必須 / オプション

デフォルト

説明

bind

bind または cfc 属性が必須

呼び出す CFC メソッド、JavaScript 関数、または URL を指定するバインド式です。バインド式の指定に関する詳細については、『ColdFusion アプリケーションの開発』のBinding data to form fieldsを参照してください。

この属性は cfc 属性と一緒には使用できません。

cfc

bind または cfc 属性が必須

プロキシを作成する CFC です。CFC へのパスをドット区切り形式で指定します。パスは、絶対ファイルパスで指定しても、CFML ページの場所を基準とした相対ファイルパスで指定してもかまいません。たとえば、ColdFusion ページの cfcs サブディレクトリに myCFC という CFC がある場合は、cfcs.myCFC と指定します。

CFC によって別の CFC が拡張される場合は、拡張された CFC メソッドも JavaScript プロキシに対して使用可能になります。

UNIX ベースのシステムでは、まず指定された属性値に対応する名前またはパス (ただしすべて小文字) のファイルが検索されます。該当するファイルが見つからない場合は、大文字と小文字の区別も含めて属性値と完全に一致するファイル名またはパスが検索されます。

この属性は bind 属性と一緒には使用できません。

jsclassname

オプション

cfc 属性の値

CFC を表す JavaScript プロキシクラスに使用する名前です。

この属性は bind 属性と一緒には使用できません。

onError

オプション

bind 属性で指定したバインドが失敗したときに呼び出す JavaScript 関数の名前です。この関数は 2 つの引数 (エラーコードとエラーメッセージ) を取る必要があります。

この属性は cfc 属性と一緒には使用できません。

onSuccess

オプション

bind 属性で指定したバインドが成功したときに呼び出す JavaScript 関数の名前です。この関数は 1 つの引数 (bind 関数の戻り値) を取る必要があります。bind 関数が CFC 関数の場合は、戻り値が JavaScript 変数に自動的に変換されてから onSuccess 関数に渡されます。

この属性は cfc 属性と一緒には使用できません。

使用方法

ColdFusion Administrator の [サーバーの設定]-[設定] ページで [HTTP ステータスコードの有効化] オプションが選択されていることを確認してください。このオプションが選択されていないと、CFC 関数の呼び出しでエラーが発生したかどうかをプロキシが判断できないので、エラーハンドラを呼び出せません。

bind 属性が設定された cfajaxproxy タグでは、バインド式に指定されていないコントロールは更新されません。

bind 属性に URL を指定する場合は、onSuccess の引数に対応するオブジェクト、配列、または単純値の JSON 表記が HTTP 応答として返される必要があります。

CFC プロキシの作成

cfc 属性が設定された cfajaxproxy タグを使用すると、Web クライアント上の CFC を表す JavaScript プロキシが生成されます。このタグとプロキシには次の特徴があります。

  • プロキシは、各 CFC リモート関数に対応する関数を 1 つ提供します。クライアントサイドの JavaScript コードでこれらの関数を呼び出すと、サーバー上の CFC 関数がリモートで呼び出されます。

  • プロキシは、クライアントとサーバーのやり取りを設定するための関数を提供します。これらの関数によって、プロキシがサーバーとやり取りするときに使用する XMLHttpRequest 呼び出しの HTTP メソッドと同期モードが設定されます。また、非同期呼び出しの場合の JavaScript コールバックハンドラとエラーハンドラも指定できます。

  • JavaScript では大文字と小文字が区別されるので、クライアントに送信する ColdFusion の構造体やスコープに指定されているキーの大文字と小文字が一致していることを確認します。ColdFusion の変数名や構造要素名は、デフォルトでは大文字で記述されます(myStruct["myElement"]="value" のように連想配列表記法で名前を指定すると、構造体の要素名を小文字で作成できます)。たとえば、クエリーを表すために ColdFusion の serializeJSON タグで生成される JSON オブジェクト内の 2 つの配列のキーは、columnsdata ではなく、COLUMNSDATA になります。

AJAX CFC プロキシの使用方法の詳細については、『ColdFusion アプリケーションの開発』のUsing AJAX Data and Development FeaturesUsing ColdFusion AJAX CFC proxiesを参照してください。

注意: プロキシは、呼び出した CFC 関数に _CF_NODEBUG というブール型の引数を渡します。この値が true の場合、ColdFusion はデバッグ情報を追加せずに応答を送信します (通常は、応答の最後にデバッグ情報が追加されます)。この動作により、JSON 以外のテキスト (つまりデバッグ情報) が AJAX リクエストに対する JSON 応答に含まれなくなります。

CFC プロキシユーティリティ関数

cfc オプションを使用する場合は、サーバーとのやり取りを制御するために、次の関数が JavaScript プロキシオブジェクトによって提供されます。

関数

説明

setAsyncMode()

呼び出しモードを非同期に設定します。プロキシ関数を呼び出したときに呼び出し元のスレッド (ページ処理を行っているクライアントシステムの Java スレッド) がブロックされないので、サーバーからの応答を待っている間もページ処理を続行できます。

プロキシは、サーバーからの応答を使用して、setCallbackHandler 関数で指定されている関数を呼び出します。エラーが発生した場合、プロキシは setErrorHandler 関数で指定されているエラーハンドラを呼び出します。

setCallbackHandler(<関数>)

非同期呼び出しの場合のコールバックハンドラを指定します。この <関数> パラメータは、引数として呼び出す JavaScript 関数です。

このコールバック関数は 1 つのパラメータ (プロキシによって JSON 表記から JavaScript 表記にシリアル化解除された CFC からの戻り値) を取る必要があります。

このメソッドは、自動的に呼び出しモードを非同期に設定します。

setErrorHandler(<関数>)

非同期呼び出しでエラーが発生した場合にプロキシが呼び出すエラーハンドラを設定します。この <関数> パラメータは、呼び出す JavaScript 関数です。

このエラーハンドラ関数は次の 2 つのパラメータを取る必要があります。

  • HTTP エラーコード

  • ステータスメッセージ

このメソッドは、自動的に呼び出しモードを非同期に設定します。

setForm(ID)

この関数の直後に呼び出されたプロキシ関数から渡された引数に、ID 属性で指定されているフォームのフィールドの名前と値を追加します。

詳細については、『ColdFusion アプリケーションの開発』のSubmitting data to a CFCを参照してください。

setHTTPMethod("<メソッド>")

呼び出しに使用する HTTP メソッドを設定します。この "<メソッド>" パラメータでは、次のいずれかの値を指定する必要があります (大文字と小文字は区別されません)。

  • GET (デフォルトのメソッド)

  • POST

setQueryFormat(<形式>)

ColdFusion クエリーデータを返す JSON 形式を指定します。パラメータの有効な値は次のとおりです。

  • row: (デフォルト) 列名と行配列の配列の 2 つのエントリを含む JSON オブジェクトとしてデータを送信します。

  • column: WDDX クエリー形式を表す JSON オブジェクトとしてデータを送信します。このオブジェクトには、3 つのエントリ (行数、列名を含む配列、キーが列名で値が列データを含む配列であるオブジェクト) が含まれています。

クエリー形式の詳細については、SerializeJSONを参照してください。

setReturnFormat(<形式>)

CFC 関数から返される結果の形式を指定します。ColdFusion では、関数の戻り値が指定した形式に変換されてからクライアントに返されます。

パラメータの有効な値は次のとおりです。

  • json (この関数を使用しない場合のデフォルトの形式)

  • plain

  • wddx

plain を指定し、サーバーからのレスポンスの "content-type" ヘッダを text/xml に設定した場合は、プロキシから呼び出し元またはコールバック関数に XML オブジェクトが返されます。コンテンツタイプが text/xml に設定されていない場合、サーバーからの戻り値はそのまま返されます。

この関数は、ブラウザに XML またはプレーン文字列を返す場合に役立ちます。

setSyncMode()

呼び出しモードを同期 (デフォルトの同期モード) に設定します。呼び出し元のスレッドは、応答が返されるまでブロックされたままになります。エラーが発生した場合は、プロキシから例外が返されます。同期モードでは、CFC プロキシ内のメソッドから呼び出し元に直接 CFC メソッドの結果が返されます。

次の例では、リモート CFC メソッドを使用して従業員ドロップダウンリストを設定しています。リストから名前を選択すると、CFC メソッドが呼び出されて従業員に関する情報が取得され、結果が表示されます。

アプリケーションページには次の行が含まれています。

<!--- The cfajaxproxy tag creates a client-side proxy for the emp CFC. 
        View the generated page source to see the resulting JavaScript.  
        The emp CFC is in the components subdirectory of the directory that 
        contains this page. ---> 
<cfajaxproxy cfc="components.emp" jsclassname="emp"> 
 
<html> 
    <head> 
        <script type="text/javascript"> 
         
            // Function to find the index in an array of the first entry  
            // with a specific value. 
            // It is used to get the index of a column in the column list. 
            Array.prototype.findIdx = function(value){ 
                for (var i=0; i < this.length; i++) { 
                    if (this[i] == value) { 
                        return i; 
                    } 
                } 
            } 
 
            // Use an asynchronous call to get the employees for the  
            // drop-down employee list from the ColdFusion server. 
            var getEmployees = function(){ 
                // create an instance of the proxy.  
                var e = new emp(); 
                // Setting a callback handler for the proxy automatically makes 
                // the proxy's calls asynchronous. 
                e.setCallbackHandler(populateEmployees); 
                e.setErrorHandler(myErrorHandler); 
            // The proxy getEmployees function represents the CFC 
            // getEmployees function. 
                e.getEmployees(); 
            } 
             
            // Callback function to handle the results returned by the 
            // getEmployees function and populate the drop-down list. 
            var populateEmployees = function(res) 
            { 
                with(document.simpleAJAX){ 
                    var option = new Option(); 
                    option.text='Select Employee'; 
                    option.value='0'; 
                    employee.options[0] = option; 
                    for(i=0;i<res.DATA.length;i++){ 
                        var option = new Option(); 
                        option.text=res.DATA[i][res.COLUMNS.findIdx('FIRSTNAME')] 
                            + ' ' + res.DATA[i][[res.COLUMNS.findIdx('LASTNAME')]]; 
                        option.value=res.DATA[i][res.COLUMNS.findIdx('EMP_ID')]; 
                        employee.options[i+1] = option; 
                    } 
                }     
            } 
 
            // Use an asynchronous call to get the employee details. 
            // The function is called when the user selects an employee. 
            var getEmployeeDetails = function(id){ 
                var e = new emp(); 
                e.setCallbackHandler(populateEmployeeDetails); 
                e.setErrorHandler(myErrorHandler); 
            // This time, pass the employee name to the getEmployees CFC 
            // function. 
                e.getEmployees(id); 
            } 
            // Callback function to display the results of the getEmployeeDetails 
            // function. 
            var populateEmployeeDetails = function(employee) 
            { 
                var eId = employee.DATA[0][0]; 
                var efname = employee.DATA[0][1]; 
                var elname = employee.DATA[0][2]; 
                var eemail = employee.DATA[0][3]; 
                var ephone = employee.DATA[0][4]; 
                var edepartment = employee.DATA[0][5]; 
 
                with(document.simpleAJAX){ 
                    empData.innerHTML =  
                    '<span style="width:100px">Employee Id:</span>'  
                    + '<font color="green"><span align="left">'  
                    + eId + '</font></span><br>'  
                    + '<span style="width:100px">First Name:</span>'  
                    + '<font color="green"><span align="left">'  
                    + efname + '</font></span><br>'  
                    + '<span style="width:100px">Last Name:</span>'  
                    + '<font color="green"><span align="left">'      
                    + elname + '</font></span><br>'  
                    + '<span style="width:100px">Email:</span>' 
                    + '<font color="green"><span align="left">'  
                    + eemail + '</span></font><br>'  
                    + '<span style="width:100px">Phone:</span>'  
                    + '<font color="green"><span align="left">'  
                    + ephone + '</font></span><br>'  
                    + '<span style="width:100px">Department:</span>'  
                    + '<font color="green"><span align="left">'  
                    + edepartment + '</font></span>'; 
                } 
            } 
 
            // Error handler for the asynchronous functions. 
            var myErrorHandler = function(statusCode, statusMsg) 
            { 
                alert('Status: ' + statusCode + ', ' + statusMsg); 
            } 
             
        </script> 
    </head> 
 
    <body> 
        <!--- The form to display the employee drop-down list and  
        employee data. ---> 
        <form name="simpleAJAX" method="get"> 
        List of Employees:&nbsp;&nbsp;&nbsp; 
        <select name="employee" onChange="getEmployeeDetails(this.value)"> 
            <script language="javascript"> 
                getEmployees(); 
            </script> 
        </select> 
        <br><br> 
        <span id="empData"></span> 
        </form>     
    </body> 
</html>

データソースからデータを取得する次のコンポーネントは、"application" ディレクトリの "components" サブディレクトリの "emp.cfc" というファイルに含める必要があります。この CFC は、ColdFusion に付属する cfdocexamples データソースを使用します。

<cfcomponent> 
    <cfset this.dsn = "cfdocexamples"> 
    <cffunction name="getEmployees" access="remote" returnFormat="json" 
            output="false"> 
        <cfargument name="empid" required="no" type="string" default="0"> 
        <cfquery name="qryEmp" datasource="#this.dsn#"> 
            select * from Employees  
            <cfif empid neq 0> 
            where Emp_ID = #empid# 
            </cfif> 
        </Cfquery> 
        <cfreturn qryEmp> 
    </cffunction> 
</cfcomponent>