使用Play框架与Java时形成父/子 [英] Parent/Child forms when using Playframework with Java

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

问题描述

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

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;
}






我想做一个用户填写表单以填充问题列表。我读了很多材料和SO问题,但是我无法理解如何用表格做我想要的。我知道我可以使用DynamicForms以其他方式完成它,这不是我想要的。我的想法是它可以这样做:


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>


}

但是当我尝试使用答案时对象和它替代品一个大的 NullPointerexception 在我脸上爆炸:

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));

我想念更多关于它的文档和示例以及其他相关内容。甚至官方网站也没有提供大量的例子。特别是在处理Java时。这让人觉得框架已经过时或被其他技术所取代?

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?

我使用Play版本2.4.6。

I use version 2.4.6 of Play.

推荐答案

这是记录在案的这里,特别是如何处理重复的值。当然,文档总是可以改进的。请打开问题,提出此问题。此外,这并不表示框架已经过时或被其他人超越(实际上,Play 2.5即将发布且社区正在增长)。

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.

models / Question.java

models/Question.java:

package models;

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

models / Answer.java

models/Answer.java:

package models;

import java.util.List;

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

models / Alternative.java

models/Alternative.java:

package models;

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



控制器和路线:



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

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));
    }
}

注意指数 action我如何声明表单< 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>
  }
}

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

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=""/>

注意如何命名参数来表示订单以及<$ c $的相关不同字段c>替代对象。

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

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

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"
      }
    ]
  }
}

这篇关于使用Play框架与Java时形成父/子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆