2011-03-01 109 views
4

我正在使用命名格式報告[{field-name}]爲我的ColdFusion應用程序構建一個表單,當使用RoR或CFWheels時,會在後端調用包含所有我的字段名稱。我正在使用FW/1,所以我所有的表單字段都被放入RC範圍,而不是保留在Form範圍中。我知道可以將表單字段轉換爲ColdFusion結構,因爲正如我所說的,CFWheels就是這樣做的。我只是不知道如何讓我的應用程序做到這一點。ColdFusion將表單值轉換爲結構

這裏是我講的

<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> 
+1

FWIW,你的表格範圍已經是一個結構。所有變量範圍都是如此。 – ale 2011-03-01 16:27:14

+0

@Al是的所有變量範圍都有自己的結構,但在FW/1中,我的表單和url範圍與其他一些東西混合在一起。就我所知,我只需要我的表單範圍,但無法訪問。 – 2011-03-01 17:19:23

+1

正如Al所說,form是一個可以像其他任何結構一樣操作的結構。 – 2011-03-01 17:19:43

回答

4

亞當正確的上下文中,但他的代碼片斷是錯誤的。

,將工作的函數是這樣的:

<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外)它完美地工作。你所做的只是傳入一個結構體(在我的例子中是來自FW/1的Rc結構體),它包含什麼應該是結構體,但是顯示爲字符串,並且你將返回一個嵌套結構體。

例子:

<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> 
+0

+1爲正確的功能。 ;) – 2011-03-11 15:41:40

3

形式的一部分,所以你需要做改變的最基本的形式是這樣的:

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>