Как анализировать возврат JSON из ColdFusion CFC?

Я упростил этот код для простоты объяснения.

У меня есть страница cfm, где пользователь нажимает на строку таблицы и получает идентификатор. Я хочу отправить этот идентификатор в CFC, выполнить там запрос и вернуть результаты обратно на страницу cfm.

Вот как выглядит JQuery.

$.ajax({
    url: "test.cfc?method=testFunction",
    data: {ID:123456},
    success: function(response) {
        $("#div1").html(response);
    }
});

а вот как выглядит cfc.

<cfcomponent>
    <cffunction name="testFunction" access="remote" returnType="query" returnFormat="JSON">
           <cfquery name="testQuery" datasource="x">
                Select ID, NAME
                From Table
                Where ID = '#url.ID#'   
            </cfquery>

            <cfreturn testQuery>
    </cffunction>
</cfcomponent>

РЕДАКТИРОВАТЬ - АЛЬТЕРНАТИВНЫЙ МЕТОД CFC

<cffunction name="testFunction" access="remote">
    <cfquery name="testQuery" datasource="x">
                Select ID, NAME
                From Table
                Where ID = '#url.ID#'   
            </cfquery>

    <cfset response = [] />

    <cfoutput query="testQuery">
        <cfset obj = {
            "ID" = ID,
            "NAME" = NAME               
         } />
        <cfset arrayAppend(response, obj) />
    </cfoutput>

    <cfprocessingdirective suppresswhitespace="Yes"> 
        <cfoutput>
            #serializeJSON(response)#
        </cfoutput>
    </cfprocessingdirective>

    <cfsetting enablecfoutputonly="No" showdebugoutput="No">
</cffunction>

Как показывает функция успеха в вызове ajax вверху, div1 будет заполнен ответом JSON, который выглядит следующим образом.

{"COLUMNS":["ID","NAME"],"DATA":[[123456,"John"]]}

РЕДАКТИРОВАТЬ - АЛЬТЕРНАТИВНЫЙ ОТВЕТ

[{"ID":123456,"NAME":"John"}]   

Затем я хочу иметь возможность использовать и выводить данные из этого ответа JSON где-нибудь на моей странице. Как я могу это сделать? Мне трудно понять разбор этих данных. Моей главной задачей является получение этих данных из формата массива, чтобы я мог выводить их в поля формы на моей странице.


person madvora    schedule 05.06.2014    source источник


Ответы (3)


CF11: поддерживается, см. serialization.serializeQueryAs в документе.

CF10 или ниже: верните queryToArray(testQuery), не забудьте использовать var-scope для testQuery.

private function queryToArray(q) {
    var s = [];
    var cols = q.columnList;
    var colsLen = listLen(cols);
    for(var i=1; i<=q.recordCount; i++) {
        var row = {};
        for(var k=1; k<=colsLen; k++) {
            row[lcase(listGetAt(cols, k))] = q[listGetAt(cols, k)][i];
        }
        arrayAppend(s, row);
    }
    return s;
}

ссылка: http://www.raymondcamden.com/index.cfm/2014/5/8/ColdFusion-11s-new-Struct-format-for-JSON-and-какиспользовать-это-в-ColdFusion-10

ИЛИ в качестве альтернативы используйте: https://github.com/cutterbl/serializeCFJSON для анализа набора данных запроса CF на на стороне клиента с помощью Javascript.

person Henry    schedule 05.06.2014
comment
На самом деле у меня была альтернативная функция, которая может возвращать набор данных в формате массива, если предположить, что это правильно... code[{ID:123456,NAME:John}]code Однако мой вопрос заключается в том, что я могу сделать с этими данными на страница, как только я получу ее обратно? Мое намерение состоит в том, чтобы заполнить им поля формы. Прямо сейчас, в функции успеха, я просто показываю это в #div1, просто чтобы убедиться, что я получаю его обратно. Я просто не знаю, как вытащить данные из этого массива и использовать их на странице. - person madvora; 06.06.2014
comment
в этом случае вы можете следовать некоторым руководствам по jQuery. По сути, как только данные поступили в клиентский браузер через AJAX, вы можете делать с ними что угодно с помощью JavaScript. - person Henry; 06.06.2014

Я придумал лучший способ сделать это.

  1. Пусть cfc возвращает результаты запроса только с фигурными скобками, а не массив со скобками.

    <cfcomponent>
        <cffunction name="testFunction" access="remote">
             <cfquery name="testQuery" datasource="x">
                 Select ID, NAME
                 From Table
                 Where ID = '#url.ID#'   
             </cfquery>
    
        <cfoutput query="testQuery">
            <cfset obj = {
                "ID" = ID,
                "NAME" = NAME               
             } />
        </cfoutput>
    
        <cfprocessingdirective suppresswhitespace="Yes"> 
            <cfoutput>
                #serializeJSON(obj)#
            </cfoutput>
        </cfprocessingdirective>
    
        <cfsetting enablecfoutputonly="No" showdebugoutput="No">
    </cffunction>
    
    1. JQuery выглядит так

      $.ajax ({
          //location of the cfc
          url: "test.cfc",
          //function name and url variables to send
          data: {method:'functioname', ID:ID},
          //function run on success can the returned json object and split it out each field to a form field.  Here I'm just showing one field in the alert.
          success: function(obj) {
               var parsedjson = $.parseJSON(obj);
               alert(parsedjson.ID);
          }
      });
      
person madvora    schedule 09.06.2014
comment
где в вашем ответе появляется «ответ»? - person Sajjan Sarkar; 09.01.2015
comment
@SajjanSarkar В примере madvora переменная «ответ» должна быть изменена на «obj» или наоборот. Тогда это работает. - person mdrewlo; 07.10.2015
comment
Ты прав. Я обновил его, чтобы он был obj для имени переменной. - person madvora; 21.01.2016

(Слишком долго для комментариев)

Несколько улучшений для упрощения и укрепления кода

  1. Нет необходимости в cfoutput или cfsetting и внутри функции. Просто верните необработанную структуру «как есть». Чтобы автоматически преобразовать ответ в JSON, просто добавьте параметр URL ?returnformat=json к вашему вызову ajax.

  2. Добавьте dataType: "json" к вашему вызову ajax, и jQuery автоматически проанализирует ответ в объект JSON.

  3. Не забудьте локализовать все локальные переменные функции с помощью VAR или LOCAL.

  4. Как правило, вы хотите избежать прямого доступа к области URL из функции. Вместо этого определите идентификатор в качестве аргумента. Затем укажите в запросе ARGUMENTS.ID вместо URL.ID.

JQuery

        $.ajax({
            type: "GET",
            url: "test.cfc",
            // return the result as JSON
            data: {method: "testFunction", ID:someID, returnFormat: "JSON"},
            // automatically parse JSON response 
            dataType: "json", 
            success: function (response) {
                // check RECORDCOUNT to determine if ID was found
                alert("ID="+ response.ID);
            },
            error: function (request, status, error)
            {
                // do something if call fails..
                alert(error); 
            }
        });

CFC:

    <cfcomponent>
        <cffunction name="testFunction" access="remote" returntype="struct">
            <cfargument name="ID" type="string" required="true">

            <cfquery name="LOCAL.testQuery" datasource="x">
                 Select ID, NAME
                 From Table
                 Where ID = <cfqueryparam value="#arguments.ID#" cfsqltype="cf_sql_varchar">
            </cfquery>

            <!--- note, this assumes the query only ever returns 0 or 1 record --->
            <cfset Local.obj = { recordCount=testQuery.recordCount, ID=testQuery.ID, Name=testQuery.Name }>

            <cfreturn Local.obj>
        </cffunction>
    </cfcomponent>
person Leigh    schedule 21.01.2016