JSON, возвращенный из удаленной CFC, не работает - PullRequest
6 голосов
/ 27 сентября 2011

У меня есть удаленный CFC, который возвращает структуру.Это вызывается с помощью cfajaxproxy.Я хочу, чтобы возвращаемый JSON был в порядке, т.е. сначала в структуру, сначала в объект JSON.Однако возвращаемый JSON находится в смешанном порядке.

Вот удаленная функция.

<cfcomponent displayname="validation" hint="">
    <cffunction name="validateForm" displayname="validateForm" hint="" access="remote" verifyClient="yes" returntype="struct">

        <cfargument name="formVals" type="struct" required="yes">

        <cfset errors = StructNew()>

        <cfif formVals.project neq "project">
              <cfset errors["project"] = "Invalid project name." />
        </cfif>

        <cfif Len(formVals.description) eq 0>
             <cfset errors["description"] = "Please enter a description." />
        </cfif>

        <cfif StructIsEmpty(errors)>
            <cfset errors["message"]["type"] = "success">
            <cfset errors["message"]["text"] = "Client and server-side validation passed successfully.">
            <cfset errors["areErrors"] = false>
        <cfelse>
            <cfset errors["message"]["type"] = "validation">
            <cfset errors["message"]["text"] = "Please fix the errors, and resubmit.">
            <cfset errors["areErrors"] = true>
        </cfif>

        <cfreturn errors />

    </cffunction>
</cfcomponent>

Это cfajaxproxy, который я установил в верхней части страницы формы.

<cfajaxproxy cfc="validation" jsclassname="validation">

Вот вызов удаленной функции в обработчике onSubmit моей формы.

var v = new validation();
v.setHTTPMethod("POST");
var errors = v.validateForm(o);

Вот данные (переменная выше), которые отправляются функции вpost request.

{"formVals":{"project":"","description":""}}

Вот ответ JSON, возвращенный функцией.

{"message":{"text":"Please fix the errors, and resubmit.","type":"validation"},"description":"Please enter a description.","project":"Invalid project name.","areErrors":true}

Я хочу, чтобы ответ был в том же порядке, в котором была создана структура, которая выглядела бы так.

{"project":"Invalid project name.","description":"Please enter a description.","message":{"text":"Please fix the errors, and resubmit.","type":"validation"},"areErrors":true}

Таким образом, когда я перебираю ответ, я могу установить фокус на первое поле формы с ошибкой в ​​нем.

var focusSet = false;

$.each(errors, function(key, val){
    //alert(key + ': ' + val);
    if(key != 'message' && key != 'areErrors') {
        var fi = $('#' + key).parents('.formItem').filter(':first');
        fi.addClass("inError");
        fi.find('.err').filter(':first').html(val);
        if(!focusSet) {
            $('#' + key).focus();
            focusSet = true;
        }
    }
});

Прямо сейчас это помещает фокус ввторое поле формы, описание, а не в поле проекта.

Ответы [ 4 ]

7 голосов
/ 27 сентября 2011

Ключи структуры ColdFusion никогда не хранятся в каком-либо определенном порядке.Тем не менее, я нашел один пост , который показывает, как вы можете создать Java LinkedHashMap (который является Java под CF-структурой) для хранения и получения ключей в определенном порядке.

<cfset pets = CreateObject("java", "java.util.LinkedHashMap").init()>
<cfscript>
pets["Cat Name"] = "Leo";
pets["Dog Name"] = "Meatball";
pets["Fish Name"] = "Lil Fish";
pets["Bird Name"] = "PePe";
pets["Snake Name"] = "Sizzle";
</cfscript>
<cfloop collection="#pets#" item="key" >
    <cfoutput>
    #key#: #pets[key]#<br/>
    </cfoutput>
</cfloop>

РЕДАКТИРОВАТЬ: Решение Дэна (массив вместо struct), вероятно, будет гораздо проще.

5 голосов
/ 27 сентября 2011

Вы не можете (легко) управлять порядком возвращаемых данных структуры JSON, если вы не строите вручную строку для возврата этих данных. Если вы должны полагаться на порядок, то вам нужно возвращать свои ошибки в массиве, а не в структуре. Вы даже можете вернуть массив структур ошибок, и CF будет поддерживать правильный порядок массивов.

Я бы вернул ваши данные так:

<cfcomponent displayname="validation" hint="">
    <cffunction name="validateForm" displayname="validateForm" hint="" access="remote" verifyClient="yes" returntype="struct">

        <cfargument name="formVals" type="struct" required="yes">

        <cfset var retVal = StructNew() />
        <cfset var tempError = StructNew() />
        <cfset retVal.errors = ArrayNew(1) />

        <cfif formVals.project neq "project">
            <cfset tempError["key"] = "project" />
            <cfset tempError["message"] = "Invalid project name." />
            <cfset ArrayAppend(retVal.errors, Duplicate(tempError)) />
        </cfif>

        <cfif Len(formVals.description) eq 0>
            <cfset tempError["key"] = "description" />
            <cfset tempError["message"] = "Please enter a description." />
            <cfset ArrayAppend(retVal.errors, Duplicate(tempError)) />
        </cfif>

        <cfif ArrayIsEmpty(retVal.Errors)>
            <cfset retVal["message"]["type"] = "success" />
            <cfset retVal["message"]["text"] = "Client and server-side validation passed successfully.">
            <cfset retVal["areErrors"] = false>
        <cfelse>
            <cfset retVal["message"]["type"] = "validation">
            <cfset retVal["message"]["text"] = "Please fix the errors, and resubmit.">
            <cfset retVal["areErrors"] = true>
        </cfif>

        <cfreturn retVal />

    </cffunction>
</cfcomponent>

Это даст вам отдельный массив ошибок для зацикливания вместо того, чтобы обрабатывать ваши базовые ключи message и areErrors одновременно с вашими ошибками. Разбейте их на отдельную сущность, и вам будет проще перебирать их на стороне клиента.

3 голосов
/ 27 сентября 2011

struct не упорядочена в CFML (это просто Hashmap-подобная коллекция).

Если вы хотите упорядочить структуру, используйте

struct function orderedStructNew()
{
    return createObject("java","java.util.LinkedHashMap").init();
}
2 голосов
/ 27 сентября 2011

Самый простой способ, если вы хотите, чтобы что-то оставалось в порядке, использовать массив вместо структуры.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...