【问题标题】:Grails indexed parametersGrails 索引参数
【发布时间】:2009-11-28 02:52:56
【问题描述】:

我有一个具有Integer seed 属性的Team 对象列表。我想以单一形式一次编辑所有团队的种子。我确定 Grails 支持索引参数,但我无法让它工作。

这就是我所拥有的,它确实有效,但是我跳过了太多的方式,必须有更好的方法。

gsp:

<g:form action="setSeeds">
...
  <g:each in="${teams}" status="i" var="team">
    <input type="hidden" name="teams[${i}].id" value="${team.id}">
    <input type="text" size="2" name="teams[${i}].seed" value="${team.seed}">
  </g:each>
</g:form>

控制器:

def setSeeds = {
  (0..<30).each { i ->
    def team = Team.get(Integer.parseInt(params["teams[${i}].id"]))
    team.seed = Integer.parseInt(params["teams[${i}].seed"])
  }
  redirect(action:list)
}

这不是很糟糕吗?噪音太大了。我该如何做一些事情:

params.teams.each { t ->
  def team = Team.get(t.id)
  team.seed = t.seed
}

也就是说,我如何将名为 team[0].seedteam[0].idteam[1].seedteam[1].id 的参数映射到列表?

Stripes 中,您只需拥有List&lt;Team&gt; 属性,它就可以工作。我对 Grails 的期望也不低! ;-)

提前感谢您的帮助。

【问题讨论】:

    标签: grails properties indexed


    【解决方案1】:

    params 不仅仅是一个普通的 Map,它是一个 GrailsParameterMap,它会自动构建基于“.”分割参数名称的子 Map 结构。您可以通过使用以下 gsp 来利用这一点:

    <g:form action="seed">
     <g:each in="${teams}" status="i" var="team">
       <input type="hidden" name="teams.${i}.id" value="${team.id}">
       <input type="text" size="2" name="teams.${i}.seed" value="${team.seed}">
      </g:each>
     <g:submitButton name="update" value="Update" />
    </g:form>
    

    注意:名称属性中没有 []。控制器现在非常简单,使用一些黑色 Grails 魔法:

    log.error "params = ${params}"
    params.teams.findAll {k,v -> !k.contains(".")}.each { k,v ->
           bindData(Team.get(v.id), v)
    }
    

    第一个操作findAll过滤掉所有带点的参数。其余的是包含 k 中的行 ID 和 v 中的 idseed 的映射映射。

    我希望这能回答你的问题。

    【讨论】:

    • 我想知道是否有其他人在让它工作时遇到麻烦。使用 grails 1.3.4,我得到的不是预期的子图,而是子图的字符串表示形式。例如,params.toString() "[filters.1.value:123, filters:["1":["value":"123"], "1.value":"123"], action:list, controller :user]"
    • 是的,我在 2015 年遇到了各种各样的麻烦。似乎 grails 现在将所有参数值作为字符串返回,这使得 'maplist' 字符串实际上像多年前发现的 bcowdery 一样无用。跨度>
    【解决方案2】:

    我终于想出了如何在没有任何恶作剧的情况下做到这一点。

    忘记隐藏参数,只需在种子参数中使用团队 ID。在普惠制中:

    <g:form action="setSeeds"> 
    ... 
      <g:each in="${teams}" var="team"> 
        <input type="text" size="2" name="teams.seeds.${team.id}"
          value="${team.seed}"> 
      </g:each> 
    </g:form> 
    

    然后,在控制器中:

    params.teams.seeds.each { teamId, seed ->
      def team = Team.get(teamId.toInteger())
      team.seed = seed.toInteger()
      team.save()
    }
    redirect(action:list)
    

    像魅力一样工作。

    【讨论】:

      【解决方案3】:

      2015 年...... Grails 现在的工作方式略有不同,您可能会发现自己遇到了字符串而不是预期的子映射。我有一些工作要做
      类似的东西..

      params.nested.each{
                     if(!it.getKey().contains('.')){
                       //to get a map rather than a string...    
                        params.nested[it.getKey()];
                     }
                 };
      

      编辑:顺便说一句...

      具有相同名称的输入,例如

        <input name="item.choice" type="checkbox" value="3" />
        < input name="item.choice" type="checkbox" value="4"/>
      

      如果提交的数量超过一个,则将其放入列表中。所以如果上面两个都被检查了

         <input name="item.choice" type="checkbox" value="3" checked />
         < input name="item.choice" type="checkbox" value="4" checked/>
      

      你会得到一个列表。

      但是如果只检查一个,你不会得到一个列表(至少在我使用的 grails 版本中),你会得到一个值。

           <input name="item.choice" type="checkbox" value="3" checked />
           < input name="item.choice" type="checkbox" value="4" />
      

      这意味着在控制器中,如果我要做类似的事情

        params['item.choice'].each{
                def item=Item.get(it)
        }
      

      如果只提交一个项目,它会抛出一个错误。解决此问题的一种绝妙方法是

       ([]+(params['item.choice']?:[])).each{
               def item=Item.get(it)
       } 
      

      如果设置了参数而不是列表,则将值放入空列表中;如果设置了参数和列表,加号运算符会将所有单独的值添加到空列表中;如果不设置参数,则将两个空列表相加,创建一个空列表。

      【讨论】:

      • 知道为什么会这样吗?为什么嵌套的子图会损坏?
      【解决方案4】:

      不确定这是否有帮助,但您可以使用闭包,例如:

      <g:each in="${teams}">
           <p>id: ${it.id}</p>
           <p>seed: ${it.seed}</p>
      </g:each>
      

      您可能可以从这个输出 html 的内容中构建一个列表。或用它构建您的表单。

      【讨论】:

      • 我已经在使用闭包来构建表单。问题是,如何在控制器中检索索引参数来构建列表?
      猜你喜欢
      • 1970-01-01
      • 2010-12-03
      • 1970-01-01
      • 1970-01-01
      • 2018-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多