tl;dr
我需要将GSP模板中的LinkedHashMap中的数据发送给Controller,并保留元素的顺序。
我假设像JSON这样的结构化数据格式是理想的方法,但是Grails的JSON转换器不会从LinkedHashMap创建有序的JSON对象。
将LinkedHashMap数据结构从GSP发送到Controller的最佳方法是什么,这样我就可以保持顺序,但在解析数据时只做最少的工作。
长版
我正在开发一个taglib,以在表中呈现搜索结果。
在taglib中,我构造了一个LinkedHashMap,它指定用户希望为列名显示的数据列和标签。例如:
def tableFields = [firstName: "First Name", lastName: "Surname", unique_id: "Your Whizbang ID"]该地图被发送到视图,然后视图将其发送回控制器,以便从数据库检索搜索结果。我需要保持元素的顺序(因此使用了LinkedHashMap)。
我的第一个想法是将LinkedHashMap转换为JSON字符串,然后通过隐藏的form元素将其发送到控制器。所以,
import grails.converters.JSON
//taglib class and other code
def tableFields = [firstName: "First Name", lastName: "Surname", unique_id: "Your Whizbang ID"] as JSON但是,这会在HTML中创建像这样的JSON对象。我把它放在一个隐藏字段的值属性中。
<input type="hidden" name="columns" value="{"firstName": "First Name", "lastName": "Surname", "unique_id": "Your Whizbang ID"}" id="columns">这里是JSON对象本身。
{"firstName": "First Name", "lastName": "Surname", "unique_id": "Your Whizbang ID"}您可以看到,JSON字符串的属性与JSON字符串中的LinkedHashMap的顺序相同。但是,JSON对象实际上不应该保留其属性的顺序。因此,当我的控制器接收到列参数,并在其上使用JSON.parse()方法时,它将创建一个普通的ol‘无序HashMap,而不是LinkedHashMap。因此,当我将这些列呈现到HTML表中时,我的搜索结果中的列以错误的顺序显示。
至少有一个人也遇到了类似的问题。在运行as LinkedHashMap ()之后添加JSON.parse()并不会削减它,因为.parse()方法会破坏get的顺序。
丹尼尔·伍兹在对上述帖子的答复中指出:
如果grails数据绑定器不适合您,那么您应该能够覆盖隐式属性设置器,将对象强制转换为您最喜欢的Map实现。
我假设他说我可以编写自己的解析器,这将遵守JSON元素的顺序(尽管技术上不应该这样)。我还可以编写自己的转换器,以便生成的JSON元素如下所示:
{[{firstName: "First Name"}, {lastName: "Surname"}, {unique_id "Your Whizbang ID"}]}不过,我有点害怕JSON解析器会如何处理这个问题。我能拿回一份HashMaps的清单吗?
同样,我真正的问题是--从GSP向Controller发送LinkedHashMap数据结构的最佳方式是什么,这样我就可以保持顺序,但在解析数据时只做最少的工作?--我假设这是JSON,但是我非常高兴地被告知,“为什么不只是.”
发布于 2014-01-07 20:48:30
现在我要做的是传递当前的JSON对象和一个可以迭代的列表。在GSP模板中,如下所示:
<g:hiddenField name="columns" value="${colJson}"/>
<g:hiddenField name="columnOrder" value="${columns.collect{it.key}}"/>其中columns是LinkedHashMap。
然后,在得到这些参数的控制器中,我这样做:
def columnTitles = params.columnOrder.tokenize(",[] ")
def unorderedColumns = JSON.parse(params.columns)
def columns = columnTitles.collectEntries{ [(it): unorderedColumns[it]] }不优雅,但它确实有效,它所需的重构比Joe的建议要少一些。
发布于 2014-01-07 20:41:10
我认为问题在于Java/Groovy集合的性质与JSON的简单“它是列表或映射”性质之间的不匹配。在不进行自定义解析的情况下,我建议稍微改变一下您要发送的内容。与其试图将Groovy的LinkedHashMap概念强加到Javascriptland中,不如坚持使用Javascript理解的成语,比如地图列表。
在代码中,而不是:
def tableFields = [firstName: "First Name", lastName: "Surname", unique_id: "Your Whizbang ID"]不如:
List tableFields = [
[ name: 'firstName', label: 'First Name' ],
[ name: 'lastName', label: 'Surname' ],
[ name: 'unique_id', label: 'Your Whizbang ID' ],
]这将您转移到JSON,它维护您需要的数据(我认为),同时给JSON一些它理解的排序(列表):
<input type="hidden" name="columns" id="columns" value="[
{ "name": "firstName", "label": "First Name" },
{ "name": "lastName", "label": "Surname" },
{ "name": "unique_id", "label": "Your Whizbang ID" }
]" />不管如何处理,这将是一个稍微深一点的迭代器,但这是从一个好集合的土地到更简单的类型的代价.
https://stackoverflow.com/questions/20979606
复制相似问题