2

非常に基本的な CRUD アプリケーションをサポートするために、(jQuery などのライブラリなしで) いくつかの AJAX 要求を作成している ColdFusion 8 トレーニング アプリケーションに取り組んでいます。高レベルのアーキテクチャには、CFM ビュー、AJAX 要求を受信するリモート アクセス メソッドを備えた CFC、およびモデルとして機能し、すべてのデータベース クエリを持つ CFC が含まれます。(テーブルからすべての行を取得するなど) バインド変数をまったく必要としないデータを取得するだけの場合、AJAX クエリは正常に機能します。ただし、CFC中間レイヤーに何かを投稿しようとすると、探している値がフォームスコープで未定義であるというエラーが表示されます(私の理解では、投稿パラメーターが保存される場所です)。

JS AJAX リクエストの例を次に示します。

    function addLocation(locToAdd) {
            var thisAccess = new AccessStruct("POST", "jsontest.cfc?method=addNewLocation", getLocations, "newLoc=" + JSON.stringify(locToAdd));
            accessWrapper("addLoc", thisAccess);

    function accessWrapper(action, accessDef) {
            var ajaxRequest = new XMLHttpRequest();
            var nextStep;
            if (action != "getLocs") {
                nextStep = getLocations;
            } else {
                nextStep = buildTable;
            }

            ajaxRequest.onreadystatechange = function() { // using a closure so that the callback can
                if (ajaxRequest.readyState == 4) {        //   examine the request and nextStep
                    if (ajaxRequest.status == 200) {
                        if (nextStep != null) {
                            nextStep(ajaxRequest);
                        }
                        return true;
                    } else {
                        alert("Request Could Not Be Completed; Errors On Page");
                        return false;
                    }
                }
            }
            ajaxRequest.open(accessDef.method, accessDef.url, true);
            ajaxRequest.send("newLoc=" + accessDef.params);
    }


    function Loc(locCode, parLocCode, name, addrL1, addrL2,
                            city, stateProv, postal, locTypeCode) {
            this.locCode     = locCode;
            this.parLocCode  = parLocCode;
            this.name        = name;
            this.addrL1      = addrL1;
            this.addrL2      = addrL2;
            this.city        = city;
            this.stateProv   = stateProv;
            this.postal      = postal;
            this.locTypeCode = locTypeCode;
        }

        function AccessStruct(method, url, nextStep, params) {
            this.method   = method;
            this.url      = url;
            this.nextStep = nextStep;
            this.params   = params;
        }

基本的に、このページで起こっていることは、すべての場所 (loc) レコードが入力されたテーブルが「ユーザー」に対してレンダリングされていることです。新しいユーザーを追加するためのフォームがあり、追加ボタンをクリックすると、入力した情報を含む Loc 構造が作成され、addLocation 関数に渡されます。これにより、リクエスト URL、メソッド、コールバックとして機能する関数の名前、およびポスト パラメータを含む Access 構造が作成されます。これはすべて、XMLHttpRequest を作成して AJAX 要求を処理する accessWrapper 関数に渡されます。

問題が報告されている中間層 CFC 内の cffunction は次のとおりです。DAO CFC は他の場所でテストされており、このプロセス中にも到達していないため (中間 [またはコントローラー] レベルで失敗しているため)、あえて投稿しません。

 <cffunction name="addNewLocation" output="false" access="remote">
    <cfset var deserializedLocation = "">
    <cfscript>
        deserializedLocation = DeserializeJSON(Form.newLoc);
    </cfscript> 
    <cfobject component="locationDAO" name="locationDAOObj">
    <cfinvoke
        component="#locationDAOObj#"
        method="addLocation">
        <cfinvokeargument name="code" value="#deserializedLocation.locCode#">
        <cfinvokeargument name="parentCode" value="#deserializedLocation.parLocCode#">
        <cfinvokeargument name="name" value="#deserializedLocation.name#">
        <cfinvokeargument name="addr1" value="#deserializedLocation.addrL1#">
        <cfinvokeargument name="addr2" value="#deserializedLocation.addrL2#">
        <cfinvokeargument name="city" value="#deserializedLocation.city#">
        <cfinvokeargument name="stateProv" value="#deserializedLocation.stateProv#">
        <cfinvokeargument name="postal" value="#deserializedLocation.postal#">
        <cfinvokeargument name="locationType" value="#deserializedLocation.locTypeCode#">
    </cfinvoke>
</cffunction>

リクエスト応答のエラー: 500 Element NEWLOC is undefined in FORM

前に言ったように、改ざんデータでリクエストを確認しましたが、問題ないようです。偉大な人々が提供できるかもしれないあらゆる助けを前もって感謝します!

4

2 に答える 2

4

CFC への Ajax ポストを行う場合は、必ず FORM スコープが存在します。

この例では、フォーム データを Ajax 経由で CFC 関数に引数なしで POST し、FORM スコープの JSON 形式を返します。はい、文書化するための引数が必要であり、必須/不要とデータ型を指定する必要がありますが、必須ではありません。

jQuery を使用していない理由はありますか? それはおそらくあなたの人生をずっと楽にするでしょう。

フォーム データを Ajax 呼び出しに送信する方法に問題があるはずです。FireBug を使用して Ajax 呼び出しを監視すると、POST されたパラメーターを確認できます。

HTML

<html>
    <head>
        <title>Ajax POST to CFC</title>
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
        <script type="text/javascript" src="test.js">
    </head>
    <body>

        <form id="foo" action="" method="post">

            <input type="text" id="a" name="a" value="Hello" />
            <br />
            <input type="text" id="b" name="b" value="Goodbye" />
            <br />

            <textarea id="data" cols="30" rows="10" disabled="true"></textarea>
            <br />
            <input type="button" id="btnSubmit" value="Do Ajax!" />

        </form>

    </body>

</html>

JavaScript

$(document).ready(function() {
    $('#btnSubmit').on('click', function() {
        $.ajax({
            asynch : true,
            type : 'POST',
            dataType : 'json',
            url : 'test.cfc?method=testing&returnformat=json',
            data : {
                a : $('#a').val(),
                b : $('#b').val()
            },
            success : function(data, textStatus) {
                $('#data').val(JSON.stringify(data));
            }
        });
    });
});

フロン

<cfcomponent>
    <cffunction name="testing" access="remote" output="false" returntype="string">
        <cfreturn serializeJSON( form ) />
    </cffunction>> 
</cfcomponent>


古い学校、jQuery なし、単純な古い JavaScript

ここで、jQuery を使用しない Ajax POST の簡単な例を見つけました: http://www.openjs.com/articles/ajax_xmlhttp_using_post.php

HTML
jQuery SCRIPT タグを削除し、他の SCRIPT を test-nojq.js に変更し、送信ボタンを変更して onclick イベントを追加します。

<input type="button" id="btnSubmit" value="Do Ajax!" onclick="doSubmit();" />

JavaScript: test-nojq.js

function doSubmit(){
    var http = new XMLHttpRequest();
    var url = "test.cfc";
    var params = "method=testing&returnformat=json";
        params += "&a=" + document.getElementById('a').value;
        params += "&b=" + document.getElementById('b').value;
    http.open("POST", url, true);
    //Send the proper header information along with the request
    http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    http.setRequestHeader("Content-length", params.length);
    http.setRequestHeader("Connection", "close");
    http.onreadystatechange = function() {//Call a function when the state changes.
        if(http.readyState == 4 && http.status == 200) {
            document.getElementById('data').value = http.responseText;
        }
    }
    http.send(params);
}

于 2012-07-13T14:49:05.620 に答える
0

引数newLocにすると、うまくいくはずです。

<cffunction name="addNewLocation" output="false" access="remote">
  <cfargument name="newLoc">
  ...

</cffunction>

更新:リモートメソッドを呼び出すと、一度フォームスコープに遭遇しなかった理由がわかりません。とにかく、それは真実ではありませんが、残りの答えは依然として当てはまるはずです。

于 2012-07-12T21:41:41.430 に答える