ColdFusion Преобразование значений формы в структуру - PullRequest
4 голосов
/ 01 марта 2011

Я создаю форму для моего приложения ColdFusion, используя отчет формата имен [{field-name}], который при использовании RoR или CFWheels даст мне структуру в бэкэнде под названием report, содержащую все мои имена полей. Я использую FW / 1, поэтому все поля формы помещаются в область видимости RC, а не остаются в области формы. Я знаю, что можно преобразовать мои поля формы в структуру ColdFusion, потому что, как я уже сказал, CFWheels делает это. Я просто не знаю, как заставить мое приложение делать это.

Вот часть формы, о которой я говорю

<dl class="oneColumn">
    <dt class="first"><label for="report[name]">Name</label></dt>
    <dd><input type="text" name="report[name]" class="text" /></dd>
    <dt><label for="report[description]">Description</label></dt>
    <dd><textarea name="report[description]" class="textarea"></textarea></dd>
</dl>

Ответы [ 2 ]

4 голосов
/ 02 марта 2011

У Адама был правильный контекст, но его фрагмент кода был неправильным.

Функция, которая будет работать так:

<cffunction name="$createNestedParamStruct" returntype="struct" access="public" output="false">
    <cfargument name="params" type="struct" required="true" />
    <cfscript>
        var loc = {};
        for(loc.key in arguments.params)
        {
            if (Find("[", loc.key) && Right(loc.key, 1) == "]")
            {
                // object form field
                loc.name = SpanExcluding(loc.key, "[");

                // we split the key into an array so the developer can have unlimited levels of params passed in
                loc.nested = ListToArray(ReplaceList(loc.key, loc.name & "[,]", ""), "[", true);
                if (!StructKeyExists(arguments.params, loc.name))
                arguments.params[loc.name] = {};

                loc.struct = arguments.params[loc.name]; // we need a reference to the struct so we can nest other structs if needed
                loc.iEnd = ArrayLen(loc.nested);
                for(loc.i = 1; loc.i lte loc.iEnd; loc.i++) // looping over the array allows for infinite nesting
                {
                    loc.item = loc.nested[loc.i];
                    if (!StructKeyExists(loc.struct, loc.item))
                        loc.struct[loc.item] = {};
                    if (loc.i != loc.iEnd)
                        loc.struct = loc.struct[loc.item]; // pass the new reference (structs pass a reference instead of a copy) to the next iteration
                    else
                        loc.struct[loc.item] = arguments.params[loc.key];
                }
                // delete the original key so it doesn't show up in the params
                StructDelete(arguments.params, loc.key, false);
            }
        }
    </cfscript>
    <cfreturn arguments.params />
</cffunction>

Я протестировал его в своем приложении (за пределами CFWheels), и он работал отлично. Все, что вы делаете, это передаете структуру (в моем случае структуру Rc из FW / 1), содержащую структуры, которые должны быть структурами, но отображаются в виде строк, и вы получите структуру со вложенными структурами.

Пример:

<cfscript>
    Struct['hello[world]'] = 1;
    Struct['hello[earth]'] = 2;
    myhello = $createNestedParamStruct(Struct);
    /* Now myhello equals this:
        myhello.hello.world = 1;
        myhello.hello.eath = 2;
    */
</cfscript>
3 голосов
/ 01 марта 2011

Итак, самая основная форма изменений, которую вам нужно сделать, это:

mystruct.name = form["report[name]"];

Что вам нужно сделать, это написать цикл, который перебирает структуру формы, анализирует имена полей формы и создает структуры, подобные этим. Я предполагаю, что это уже написано где-то на CFWheels (как функция), и вы можете избавить себя от головной боли и разочарования, просто найдя его и вытянув его для себя.

Я думаю, что это так, но я не уверен:

<!--- helper method to recursively map a structure to build mapping paths and retrieve its values so you can have your way with a deeply nested structure --->
<cffunction name="$mapStruct" returntype="void" access="public" output="false" mixin="dispatch">
    <cfargument name="map" type="struct" required="true" />
    <cfargument name="struct" type="struct" required="true" />
    <cfargument name="path" type="string" required="false" default="" />
    <cfscript>
        var loc = {};
        for(loc.item in arguments.struct)
        {
            if (IsStruct(arguments.struct[loc.item])) // go further down the rabit hole
            {
                $mapStruct(map=arguments.map, struct=arguments.struct[loc.item], path="#arguments.path#[#loc.item#]");
            }
            else // map our position and value
            {
                arguments.map["#arguments.path#[#loc.item#]"] = {};
                arguments.map["#arguments.path#[#loc.item#]"].value = arguments.struct[loc.item];
            }
        }
    </cfscript>
</cffunction>
...