java - 如何命名 Play 2.2.1 表单上的 ManyToMany 复选框?

标签 java playframework playframework-2.2

我有以下两个 Java 类:

Person.java

@Entity
public class Person extends Model {
@Id
public Long id;
@ManyToOne
public Category category = new Category();
@ManyToMany
@JoinTable(joinColumns = {@JoinColumn(name = "person_id")}, inverseJoinColumns = {@JoinColumn(name = "category_id")}, name = "category_person")
public List<Category> categories = new ArrayList<>();


}

类别.java

@Entity
public class Category extends Model {
@Id
public Long id;
public String description;
@OneToMany
public Person person;
@ManyToMany(mappedBy = "categories")
public List<Person> persons = new ArrayList<>();
}

在我的 Controller 中

public static Result blank() {
    Form<Person> personForm = Form.form(Person.class);
    return ok(blank.render(personForm));
}

如何构建表单以通过复选框反射(reflect)人员和类别之间的多对多关系?

我已经尝试过

@Category.find.order("description asc").findList().map { c =>
                <input type="checkbox" name="categories[@c.id].id" value="@c.id"/> @c.description <br />
        }

但是当我尝试拯救这个人时,它告诉我

[PersistenceException: ManyToMany bean models.Category@11ac3fd does not have an Id value.]

如果我尝试

@Category.find.order("description asc").findList().map { c =>
                <input type="checkbox" name="categories[]" value="@c.id"/> @c.description <br />
        }

验证失败,它告诉我categories[0]有一个无效值

如何解决这个问题?

最佳答案

我找到了问题的解决方案:我需要注册一个自定义 DataBinder。这会告诉 Play! (特别是 Form 对象)如何将输入表单的值绑定(bind)到特定模型的实例。

首先在 Global.java 中注册自定义 DataBinder在app中创建的文件文件夹。我的包含以下代码:

public class Global extends GlobalSettings {

public void onStart(Application app) {
    Formatters.register(Category.class, new Formatters.SimpleFormatter<Category>() {
        @Override
        public Category parse(String text, Locale locale) throws ParseException {
            return Category.find.byId(Long.parseLong(text));
        }

        @Override
        public String print(Category category, Locale locale) {
            return category.id+"";
        }
    });
}

接下来,在我的表单中,我将多对多类别复选框命名如下:

<input type="checkbox" name="categories[]" value="@category.id" /> @category.description <br />

但是,这还不是全部。我必须满足必须使用填充信息重新呈现表单的情况,例如用户编辑他的个人资料。这意味着我需要预先检查用户在注册时选择的复选框。这是我使用的代码:

@defining(personForm("categories").indexes.map { i => personForm("categories")("[" + i + "]").value }) { values =>
    @Category.find.all().map { category =>
        <input type="checkbox"
        name="categories[]"
        value="@category.id"
    @if(values.contains(Some(category.id.toString()))) { checked } /> @category.description <br />
    }
}

如果你问我的话,有点复杂,但这是我必须走的路线,因为我想通过 Form<>到模板而不是 POJO。

我希望这对某人有帮助。

关于java - 如何命名 Play 2.2.1 表单上的 ManyToMany 复选框?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21660872/

相关文章:

java - 无法导入 WindowsFileAttributes

c# - 3层架构系统

postgresql - 如何使用 Postgresql 设置 Play Slick

playframework - 如何使用 Akka 2.3.x 运行 Play 2.2.x?

java - PowerShell 中手动执行和编程执行的输出不同

java - 当应用程序进入后台时,Android 绑定(bind)程序事务失败

playframework - 有什么方法可以替换 playframework 的 application.conf 中的环境变量吗?

java - 如何从 Play WSClient 的字符串创建 WSResponse 对象

scala - 使用 Gzip Play Framework 不起作用

java - Play Framework 2.2 : How to get current controller and action in java