【问题标题】:How to submit a list of Objects in Play Framework如何在 Play Framework 中提交对象列表
【发布时间】:2011-09-14 13:43:13
【问题描述】:

这是我的测试设置:

模特:

package models;

    import javax.persistence.Entity;
    import play.db.jpa.Model;

    @Entity
    public class Item extends Model {

        public String propertyA;
        public String propertyB;

        public String getFullName() {
            return this.propertyA + " - " + this.propertyB;
        }
    }

控制者:

package controllers;

import play.*;
import play.mvc.*;

import java.util.*;

import models.*;

public class Application extends Controller {

    public static void index() {
        List<Item> allItems = Item.findAll();
        render(allItems);
    }

    public static void save(List<Item> items) {
        if (items == null) {
            Logger.info("no items");
        } else {
            for (Item item : items) {
                Logger.info("item: %s",item);
            }
            Logger.info("-------");
        }
        index();
    }
}

观点:

#{extends 'main.html' /}
#{set title:'Home' /}
#{form @Application.save()}

Select Items:
<div>
    <select name="items" style="width: 200px;" multiple="multiple" size="10">
        #{list items:allItems, as: 'item'}
        <option value=${item.id} >${item.fullName}</option>
        #{/list}
    </select>
</div> 
<input type="submit" value="Save" />
#{/form}

当我在选择框中选择两个项目时,我得到以下日志输出:

06:22:20,560 INFO  ~ -------
06:22:26,991 INFO  ~ item: null
06:22:26,991 INFO  ~ item: null

看起来 play 将选择映射到 null 对象的列表。即使我将视图更改为:

<option value=${item} >${item.fullName}</option>

我得到null 值。

但是当我将控制器更改为:

public static void save(List<Long> items) {
...
}

我至少得到了一个正确 ID 的列表。

如何更改此设置,以便 play 为我的项目创建正确的映射。我更喜欢得到List&lt;Item&gt; 而不是List&lt;Long&gt;(这里我必须执行查询来获取项目列表)。

BR,雷内

更新:

如果我跑:

curl -d "items[0].id=3&items[0].propertyA=bla&items[0].propertyB=blo&items[1].id=4" http://localhost:9000/application/save

Wich 使用上述参数进行 POST,我得到:

A02:39:53,072 INFO  ~ item: bla - blo
02:39:53,072 INFO  ~ item: null - null
02:39:53,072 INFO  ~ -------

像这样它可以工作,但我不知道如何更改视图,以便它发布上述参数:-(

更新 2:

在 Felipe 的帮助下,我开始工作了。必须添加此控制器方法:

@Before(only = {"save"})
static void parseParams() {
    String[] items = params.getAll("items");
    params.remove("items");
    for (int i = 0; i < items.length; i++) {
        Item item = Item.findById(Long.parseLong(items[i]));
        params.put("items[" + i + "].id", items[i]);
        params.put("items[" + i + "].propertyA", item.propertyA);
        params.put("items[" + i + "].propertyB", item.propertyB);
    }
}

【问题讨论】:

  • 有一种方法可以使用@Before 拦截器...我会更新我的答案..

标签: playframework


【解决方案1】:

这是一个绑定问题,play 没有绑定它接收到的 long[] 参数。

来自 play 的文档:http://www.playframework.org/documentation/1.2.3/controllers#objectbinding 您需要将您选择的名称更改为items.id

它可能不起作用,因为 play 期望列表的索引为 items[i].id...

无论如何,如果这不能解决您的问题,您可以进行自定义绑定,但是当您在很多地方都需要此绑定时,如果您只执行一次,则该选项非常有用,正如您在帖子末尾所说的那样,没有理由不进行查询。 (Play会做这个查询来做这个绑定,所以你自己做不会输也不会赢)

更新 类似的东西:

@Before(only={"save"})
static void parseParams() {  
    String[] itens = params.getAll("items")
    for (int i=0;i<itens.length;i++) {
        params.put("items["+i+"].id",itens[i])
    }
}

应该可以。

另一种方法是 javascript,但它更难,更容易出错。

【讨论】:

  • 感谢它现在可以工作,我将工作版本添加到更新 2。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-14
  • 1970-01-01
  • 2017-07-26
  • 2015-03-15
  • 1970-01-01
相关资源
最近更新 更多