【问题标题】:Can Grails handle POST variables as an array?Grails 可以将 POST 变量作为数组处理吗?
【发布时间】:2014-11-03 17:06:01
【问题描述】:

如果您将以下 HTML 发布到 PHP 脚本中:

<input type="hidden" name="var[0]" value="A" />
<input type="hidden" name="var[2]" value="C" />
<input type="hidden" name="var[1]" value="B" />

您最终会得到一个名为 $_POST['var'] 的变量(本质上是一个 HashMap),其键/值如下所示:

[0] => "A"
[1] => "B"
[2] => "C"

在 PHP 中,我可以对此进行基本的数组逻辑,例如我可以看到 count($_POST['var']) == 3,我可以使用 foreach 语句对其进行迭代。

在 Grails 中是否有任何方法可以完成此操作或类似的操作?我注意到,如果我将相同类型的 HTML 传递给 Grails,则结果远不如 PHP 中的直观。我想要做的只是能够访问params.var[0]params.var[1]等等,同样能够检查params.var.length之类的东西。

但事实并非如此。 发生的是,params.var 是未定义的,但是我必须访问 request.getParameter('var[0]'),这显然是没有用的。

我意识到我可以将我的 HTML 更改为以下内容:

<input type="hidden" name="var" value="A" />
<input type="hidden" name="var" value="B" />
<input type="hidden" name="var" value="C" />

但这远非理想,因为我必须保证每次输入的 HTML 都是正确的顺序。在 PHP 中,它们出现的顺序并不重要,因为我可以直接在 name 属性中指定它,并且语言足够聪明,可以处理它。

我错过了什么吗?有没有办法在 Grails 中实现这一点?

【问题讨论】:

  • 嗯,这不是很好的行为吗? DOM 中的顺序映射到List 中的顺序。多亏了这一点,您可以更改 DOM 中的顺序(使用 JS)并在服务器端以所需的顺序绑定项目。您能否提供一个用例,这种方法不会成为骗局?发送!
  • 不!这根本不是好行为。我想也许你已经适应了不良行为,却没有意识到有更好的选择。 Grails 在这里所做的是要求 HTML 以完全正确的顺序格式化,而不需要任何选项来指定替代顺序。好的行为是默认为 HTML 中显示的顺序,但允许人们根据需要覆盖该顺序。 (如上所述,这正是 PHP 所做的。失​​去该选项肯定是降级。)
  • 嗯,默认顺序是呈现 HTML 的顺序,不是吗?另外,您将如何实现我描述的任务,即在浏览器中重新排序元素并将订单保存到后端?您需要使用 JS 更改 [...] 中的值,对吗?不是更复杂吗?
  • 从您所说的看来,Grails 现在还不是为此而构建的。如果是这样的话,那就更严格了。如果我想重新排序,我必须像你说的那样改变 DOM 中的顺序。使用 PHP,无论哪种方式都可以。您可以更改 DOM 中的顺序,或者您可以使用名称属性上的索引,然后覆盖 DOM 顺序。这限制较少。在某些情况下,这甚至根本不需要 JavaScript;您可以直接以任何您想要的顺序呈现 HTML,而不必考虑重新排序。
  • 这更好的原因是因为它可能不是我的&lt;input type="hidden"&gt; 的简单示例。它可能是&lt;input type="text"&gt;,您可能希望某些元素出现在页面上的其他元素之前,但映射到列表中后面的元素。在 PHP 中,这很容易;这似乎在 Grails 中更难做到。

标签: php grails post groovy httprequest


【解决方案1】:

实际上它在绑定数据时是默认的。请参阅http://grails.org/doc/latest/guide/theWebLayer.html#dataBinding 绑定到集合和地图

数据绑定器可以填充和更新集合和地图。以下代码显示了在域类中填充对象列表的简单示例:

class Band {
    String name
    static hasMany = [albums: Album]
    List albums
}

class Album { String title Integer numberOfTracks }

def bindingMap = [name: 'Genesis', 
                  'albums[0]': [title: 'Foxtrot', numberOfTracks: 6], 
                  'albums[1]': [title: 'Nursery Cryme', numberOfTracks: 7]]

def band = new Band(bindingMap)

assert band.name == 'Genesis' 
assert band.albums.size() == 2 
assert band.albums[0].title == 'Foxtrot' 
assert band.albums[0].numberOfTracks == 6 
// ...

另外,如果你想自己处理这个,你当然可以自己写。例如:

params.collect{it=~/${name}\[(\d+)\]/}.findAll().collectEntries{[it.group(1).toInteger(), params[it.group(0)]]}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-25
    • 1970-01-01
    • 2011-09-04
    • 1970-01-01
    • 2011-03-08
    • 2012-11-28
    • 1970-01-01
    • 2011-07-01
    相关资源
    最近更新 更多