将 Playframework 与 Java 一起使用时的父/子表单 [英] Parent/Child forms when using Playframework with Java

查看:23
本文介绍了将 Playframework 与 Java 一起使用时的父/子表单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个问题"实体,它有一个答案",其中包含一个替代方案"列表,如下所示:

public class Question extends BaseEntity {私人字符串文本;私有字符串源代码;私人字符串补充;私人回答;}

<小时>

public class Answer extends BaseEntity{私人列表<Alternative>备择方案;}

<小时>

我想制作一个表单,供用户填写问题列表.我阅读了很多材料和 SO 问题,但我无法完全了解如何使用表格来做我想做的事情.我知道我可以使用 DynamicForms 以其他方式做到这一点,这不是我想要的.我的想法是可以这样做:

@(message: String, form: play.data.Form[Question])@main("地籍查询") {<script src="@routes.Assets.at("javascripts/index.js")"></script><div class="page-header"><h1>@message</h1>

<身体><风格>.top-buffer { margin-top:12px ;}</风格><div class="container.fluid form-group">@helper.form(routes.Application.submit()) {<div class="row top-buffer"><label for="text">说明:</label><textarea id="text" name="text" class="form-control col-md-6" placeholder="Enunciado da questão" rows="5" value="@form("text").value()"></textarea>

...<div class="row top-buffer"><label for="complement">Corretas:</label><input type="text" name="correct" class="form-control col-md-6" value="@form("complement.answer.alternatives[0]").value()">

<div class="row top-buffer"><div class="row top-buffer"><input type="submit" class="btn btn-primary col-md-1" value="submit">

}

}

但是当我尝试使用 Answer 对象并且它替代"时,一个很大的 NullPointerexception 在我脸上爆炸:

 最终表格<问题>questionForm = f.bindFromRequest();最终问题 question = questionForm.get();System.out.println(问题);System.out.println(question.getText());System.out.println(question.getSourceCode());System.out.println(question.getComplement());//这里是空指针:最终列表<Alternative>替代品 =question.getAnswer().getAlternatives();替代品.forEach(p -> System.out.println(p));

我想念更多关于它和其他相关内容的文档和示例.即使是官方网站也没有提供大量示例.尤其是在处理 Java 时.这给出了一个想法,即该框架正在变得过时或被其他技术取代?

我使用 Play 的 2.4.6 版.

解决方案

这是记录在 here,特别是如何处理重复值.当然,文档总是可以改进的.请打开引发此问题的问题.此外,这并不代表该框架正在变得过时或被其他人取代(实际上,Play 2.5 即将发布且社区正在壮大).

无论如何,这里有一个关于如何像您描述的那样创建父/子表单的综合示例.请记住,我并不关心表单的样式.

您的域层次结构:

models/Question.java:

包模型;公开课问题{公共字符串文本;公共字符串源代码;公共字符串补码;公开回答答案;}

models/Answer.java:

包模型;导入 java.util.List;公共课答案{公共列表<Alternative>备择方案;}

models/Alternative.java:

包模型;公共类替代{公共布尔正确;公共字符串语句;}

控制器和路由:

现在,我有以下操作,它仅将 Question 对象及其子对象作为 JSON 返回(因为我们只对如何提交此类数据感兴趣):

包控制器;导入模型.问题;导入 play.data.Form;导入 play.libs.Json;导入 play.mvc.*;导入 views.html.*;导入静态 play.data.Form.form;公共类应用程序扩展控制器{公共结果索引(){表单<问题>形式 = 形式(问题.类);返回 ok(index.render(form));}公共结果帖子(){表单<问题>form = form(Question.class).bindFromRequest();问题 question = form.get();返回 ok(Json.toJson(问题));}}

注意在 index 操作中我是如何声明一个 Form 并将其作为参数传递给视图的.您可以在文档中查看有关如何定义表单的更多信息.让我们看看我们的路线:

GET/controllers.Application.index()POST/保存controllers.Application.post()

表单视图:

最后,我们需要创建将填充和提交数据的表单:

@(questionForm: Form[Question])@main("欢迎来玩") {@helper.form(action = routes.Application.post()) {<h2>问题:</h2>@helper.inputText(questionForm("text"))@helper.inputText(questionForm("sourceCode"))@helper.inputText(questionForm("complement"))<h3>答案:</h3>@helper.repeat(questionForm("answer.alternatives"), min = 2) {替代 =>@helper.checkbox(替代(正确"))@helper.inputText(alternative("statement"))}<button type="submit">保存</button>}}

基本上,该表单是使用 表单助手 创建的,它将处理大部分表单工作方式的各个方面(例如显示错误,每个实例).特别注意 @helper.repeat 标签:它将创建以下标记(省略不相关的部分):

答案:

<label>answer.alternatives.0.correct</label><input type="checkbox" name="answer.alternatives[0].correct" value=""/><label>answer.alternatives.0.statement</label><input type="text" name="answer.alternatives[0].statement" value=""/><label>answer.alternatives.1.correct</label><input type="checkbox" name="answer.alternatives[1].correct" value=""/><label>answer.alternatives.1.statement</label><input type="text" name="answer.alternatives[1].statement" value=""/>

注意参数是如何命名以表示订单以及与 alternative 对象的不同字段相关的.

提交表单:

最后,填写并提交表单后,您将获得以下 JSON:

<代码>{"text": "问题文本","sourceCode": "问题来源","complement": "问题补充",回答": {备择方案": [{正确":正确,"statement": "声明 1"},{正确":错误,"声明": "声明 2"}]}}

I have a "Question" entity that has a "Answer" that has a list of "Alternatives" as below:

public class Question extends BaseEntity {

    private String text;

    private String sourceCode;

    private String complement;

    private Answer answer;
}


public class Answer extends BaseEntity{
    private List<Alternative> alternatives;
}


I want to make a form to user populate with a list of questions. I read so many material and SO questions, but I cannot get how to do exactly what I want with forms. I know that I can do it in other manner using DynamicForms, this is not what I want. My idea is that it could be done this way:

@(message: String, form: play.data.Form[Question])
@main("cadastrar questão") {

    <script src="@routes.Assets.at("javascripts/index.js")"></script>
    <div class="page-header">
        <h1>@message</h1>
    </div>
    <body>
        <style>
        .top-buffer { margin-top:12px ; }
        </style>
        <div class="container.fluid form-group">
        @helper.form(routes.Application.submit()) {

            <div class="row top-buffer">
                <label for="text">Enunciado:</label>
                <textarea id="text" name="text" class="form-control col-md-6" placeholder="Enunciado da questão" rows="5" value="@form("text").value()"></textarea>
            </div>

    ...    
            <div class="row top-buffer">
                <label for="complement">Corretas:</label>
                <input type="text" name="correct" class="form-control col-md-6" value="@form("complement.answer.alternatives[0]").value()">
            </div>

            <div class="row top-buffer">
                <div class="row top-buffer">
                    <input type="submit" class="btn btn-primary col-md-1" value="submit">
                </div>
            </div>
        }
        </div>
    </body>


}

But when I try to use the Answer object and it "Alternatives" a big NullPointerexception explodes on my face:

        final Form<Question> questionForm = f.bindFromRequest();
        final Question question = questionForm.get();
        System.out.println(question);
        System.out.println(question.getText());
        System.out.println(question.getSourceCode());
        System.out.println(question.getComplement());

//Nullpointer here:
        final List<Alternative> alternatives = 
question.getAnswer().getAlternatives();

        alternatives.forEach(p -> System.out.println(p));

I miss more documentation and examples about it and other things related. Even the official website does not provide extensive examples. Especially when dealing with Java. This gives an idea that the framework is becoming obsolete or being overtaken by other technologies?

I use version 2.4.6 of Play.

解决方案

This is documented here, specifically at how to handle repeated values. Of course, documentation can always be improved. Please open an issue raising this problem. Also, this does not represent that the framework is becoming obsolete or being overtaken by others (in fact, Play 2.5 is close to being released and the community is growing).

Anyway, here is an comprehensive example about how to do a parent/child form like you described. Keep in mind that I didn't care about styling the forms.

Your domain hierarchy:

models/Question.java:

package models;

public class Question {
    public String text;
    public String sourceCode;
    public String complement;
    public Answer answer;
}

models/Answer.java:

package models;

import java.util.List;

public class Answer {
    public List<Alternative> alternatives;
}

models/Alternative.java:

package models;

public class Alternative {
    public boolean correct;
    public String statement;
}

Controllers and routes:

Now, I have the following action that just returns the Question object and its children as a JSON (since we are just interested in how to submit this kind of data):

package controllers;

import models.Question;
import play.data.Form;
import play.libs.Json;
import play.mvc.*;

import views.html.*;

import static play.data.Form.form;

public class Application extends Controller {

    public Result index() {
        Form<Question> form = form(Question.class);
        return ok(index.render(form));
    }

    public Result post() {
        Form<Question> form = form(Question.class).bindFromRequest();
        Question question = form.get();
        return ok(Json.toJson(question));
    }
}

Notice at the index action how I've declared a Form<Question> and passed it as an argument to the view. You can see more information about how to define a form at the docs. Let's see our routes:

GET     /                  controllers.Application.index()
POST    /save              controllers.Application.post()

The form view:

Finally, we need to create the form that will populate and submit the data:

@(questionForm: Form[Question])

@main("Welcome to Play") {
  @helper.form(action = routes.Application.post()) {
    <h2>Question:</h2>
    @helper.inputText(questionForm("text"))
    @helper.inputText(questionForm("sourceCode"))
    @helper.inputText(questionForm("complement"))
    <h3>Answers:</h3>
    @helper.repeat(questionForm("answer.alternatives"), min = 2) { alternative =>
      @helper.checkbox(alternative("correct"))
      @helper.inputText(alternative("statement"))
    }
    <button type="submit">Save</button>
  }
}

Basically the form was created using the form helpers which will handle most of the aspects of how the form works (like showing errors, per instance). Special attention to the @helper.repeat tag: it will create the following markup (omitting irrelevant parts):

<h3>Answers:</h3>

<label>answer.alternatives.0.correct</label>
<input type="checkbox" name="answer.alternatives[0].correct" value=""/>

<label>answer.alternatives.0.statement</label>
<input type="text" name="answer.alternatives[0].statement" value=""/>



<label>answer.alternatives.1.correct</label>
<input type="checkbox" name="answer.alternatives[1].correct" value="" />

<label>answer.alternatives.1.statement</label>
<input type="text" name="answer.alternatives[1].statement" value=""/>

Notice how the parameters are named to represent an order and also related different fields of the alternative object.

Submitting the form:

Finally, after filling and submitting the form, you will get the following JSON:

{
  "text": "Question text",
  "sourceCode": "Question source",
  "complement": "Question complement",
  "answer": {
    "alternatives": [
      {
        "correct": true,
        "statement": "Statement 1"
      },
      {
        "correct": false,
        "statement": "Statement 2"
      }
    ]
  }
}

这篇关于将 Playframework 与 Java 一起使用时的父/子表单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
Java开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆