2014-01-14 23 views
2

在我的GSP中,我有一个表单,里面填充了很多来自控制器的地图的textfields,让我把它放在一个例子中,因为我的实际表单比这个复杂得多:提交表单文本字段不正确分组

例如,如果我用users填充一堆文本框,我可以进入每个人的age,我组合起来到一个名为data地图,我想提交后处理并保存所有的信息:

<g:form useToken="true" name='example_form' action='submit'> 
    <g:each in='${users}' var='user' status='i'> 
     <g:textField name="data.${user.id}.name" value="${i.name}"> 
     <g:field name="data.${user.id}.age" value=""> 
    </g:each> 
    <button>Submit</button> 
</g:form> 

但是,当我打印出params.data在我的submit控制器,我发现不仅我得到我所创建的data地图,我也越来越在它多了一堆垃圾:

for(i in params.data){ 
    println "key: ${i.key} value: ${i.value}" 
} 

输出:

key: 0.name value: john 
key: 0 value: [age: 35, name: john] 
key: 1.name value: liz 
key: 1 value: [age: 24, name: liz] 
key: 2.name value: robert 
key: 3.name value: david 
key: 0.age value: 35 
key: 1.age value: 24 
key: 2 value: [age: 44, name: robert] 
key: 3 value: [age: 23, name: david] 
key: 3.age value: 23 
key: 2.age value: 44 

我做有问题?

预期输出:

key: 0 value: [age: 35, name: john] 
key: 1 value: [age: 24, name: liz] 
key: 2 value: [age: 44, name: robert] 
key: 3 value: [age: 23, name: david] 
+0

看起来您正在以扩展和未扩展的形式获取数据'Map' ......我认为您必须处理它。尝试在'for'循环内添加一个检查,如'if(i.value instanceof Map)'。 – nickdos

回答

1

它应该工作正是这样。当你从你的表单提交数据,您的POST请求的主体看起来是这样的:

data.0.name=john&data.0.age=35&data.1.name=liz&data.1.age=24&data.2.name=robert&data.2.age=44&data.3.name=david&data.3.age=23 

所以,这只是一个普通的字符串,表示一个普通的键 - 值映射和Grails可以解析就是如此:

['data.0.name': 'john', 'data.0.age': '35', 'data.1.name': 'liz', 'data.1.age': '24', 'data.2.name': 'robert', 'data.2.age': '44', 'data.3.name': 'david', 'data.3.age': '23'] 

但Grails开发希望简化程序员的生活,他们决定,如果该键包含一个点,该请求可能代表某种结构化数据。所以他们决定把它放到地图上,除了原始的请求数据。因此,可以用两种方式解释点 - 作为普通符号,或作为地图名称和地图键之间的分隔符。开发者应该以何种方式解释点。

0

如果您更喜欢使用像def name = params.data.0.name这样的简单易用的参数,那么您可以使用“_”来代替“。”。在控制器中,您可以在循环中使用split("_")

0

在上一篇文章中@Alexander Tokarev解释了发生了什么事。解决方案是if语句,如下所示:

for(i in params.data){ 
    if(i.key.isNumber()) { 
     println "key: ${i.key} value: ${i.value}" 
    } 
}