【问题标题】:Transforming Form Field to Object on Submit提交时将表单字段转换为对象
【发布时间】:2015-11-19 10:30:26
【问题描述】:

我对 Play Framework 比较陌生,所以我希望这可以理解。

如何告诉 play 将表单元素映射到表单类中的 Object 字段?

我有一个表单,其中包含从我的 ORM 中选择的对象名称下拉列表。下拉项的值是 ORM 对象的 ID 字段。

Java 端的表单对象有一个带有 ORM 对象类型的字段,以及一个获取字符串并将其转换为对象的设置器,但是在表单提交时,我只收到一个表单错误“无效值”,指示根本没有进行翻译。

我的模板有一个表单组件:

@helper.select(
    createAccountForm("industry"),
    helper.options(industries)
)

industries 在模板构造函数中定义为:industries: Map[String, String] 并由 ID 字符串到用户可读名称组成。

我的控制器定义了类:

public static class CreateAccountForm {
    public String name;
    public Industry industry;

    public void setIndustry(String industryId) {
        this.industry = Industry.getIndustry(Integer.parseInt(industryId));
    }
}

编辑:我在课堂上做 setter,因为 this answer 表示要这样做,但这没有用。

编辑2: 事实证明,setter 方法完全不是解决这个问题的方法。在尝试让注释正常工作后,我注意到了 Formatters.SimpleFormatter 并尝试了它。它起作用了,虽然我不明白为什么它周围的额外块是必要的。

Global.java:

public class Global extends GlobalSettings {


// Yes, this block is necessary; no, I don't know why.
{
    Formatters.register(Industry.class, new Formatters.SimpleFormatter<Industry>() {

        @Override
        public Industry parse(String industryId, Locale locale) throws ParseException {
            return Industry.getIndustry(Integer.parseInt(industryId));
        }

        @Override
        public String print(Industry industry, Locale locale) {
            return industry.name;
        }
    });

}

}

【问题讨论】:

    标签: java scala playframework-2.0


    【解决方案1】:

    当您按照文档中的描述使用表单时,Play 会将表单绑定到一个对象:https://github.com/playframework/Play20/wiki/JavaForms

    所以你的控制器应该是这样的:

     Form<models.Task> taskForm = form(models.Task.class).bindFromRequest();
     if (taskForm.hasErrors()) {
         return badRequest(views.html.tasks.create.render(taskForm));
     }
     Task task = taskForm.get();
    

    任务对象可以有一个Priority 选项列表。并且您以如下形式(视图)使用它:

    @select(editForm("priority.id"), options(Task.priorities),  'class -> "input-xlarge", '_label -> Messages("priority"), '_default -> Messages("make.choice"), 'showConstraints -> false, '_help -> "")
    

    请注意,我使用priorities.id 来告诉play 选择的值应该由优先级ID 绑定。当然还有获取任务的优先级:

    public static Map<String, String> priorities() {
        LinkedHashMap<String, String> prioritiesList = new LinkedHashMap<String, String>();
        List<Priority> priorities = Priority.getPrioritiesForTask("task");
        for (Priority orderPrio : priorities) {
            prioritiesList.put(orderPrio.getId().toString(), orderPrio.getDescription());
        }
        return prioritiesList;
    }
    

    【讨论】:

    • 如果 play 正确绑定了对象,这似乎会起作用,但事实并非如此。我确实发现我只需要为 Industry 类添加一个 Formatter。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多