播放框架-为动态字段注册自定义DataBinder [英] Play Framework - Register a custom DataBinder for dynamic fields

查看:76
本文介绍了播放框架-为动态字段注册自定义DataBinder的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用Play 2.3.7(Java),我有以下情形.

Using Play 2.3.7 (Java) I have the following scenario.

我有一个类CSVData,其中包含类型为CSVField的列表.这是这些类的属性:

I have a class CSVData which contains a list of type CSVField. Here are the attributes for these classes:

public class CSVData{

private String name;
private String description;
private String dataFilePath;
private List<CSVField> fields;
private Double latitude;
private Double longitude;


// rest of class... }

public class CSVField {
    private String name;
    private String type;

...}

制作表单输入CSVData时遇到的困难是我具有此嵌套的List<CSVField>属性,而CSVField是包含两个字符串的自定义类型.我需要这种形式是动态的,因为它应该能够接受任意数量的CSVField s(至少1个).根据 Java表单文档,看来我应该注册一个自定义DataBinder对于CSVField,但是我找不到任何使用多个输入字符串执行此操作的示例. 此示例类似,但仅绑定一个字段.

The difficulty when making a form to input CSVData is that I have this nested List<CSVField> attribute and CSVField is a custom type containing two strings. I need the form to be dynamic in that it should be able to accept an arbitrary amount of CSVFields (at least 1). According to the Java Form Documentation, it seems like I should register a custom DataBinder for CSVField, however I can't find any examples that do this with multiple input strings. This example is similar, but it only binds one field.

这是一部我想拥有哪种类型的用户输入的视频 .我使用了添加动态字段的示例代码进行了查看.我需要将文本字段(名称)和选择下拉项(类型)的组合绑定到CSVField,然后添加到CSVData对象中的List<CSVField> fields. 如何使用Play框架执行此操作?

Here is a video of what type of user input I would like to have. I made my view using this example code for adding dynamic fields. The combination of the text field (name) and select dropdown item (type) is what I need to bind to a CSVField and then add to the List<CSVField> fields in the CSVData object. How can I do this using the Play Framework?

编辑:在我的控制器中,我已经尝试过

EDIT: In my controller I have tried this

Form<CSVData> formData = Form.form(CSVData.class).bindFromRequest();

在视图中,我尝试

@helper.repeat(csvForm("fields"), min = 1) { csvField =>

    @multiDataField(csvField,
        label = "Column Name and Type",
        gsnTypes,
        help = "Enter the column names and respective types for the data items in the file")

}

multiDataField模板的位置.但是它不能正确绑定动态字段,并在fields上引发无效的验证错误.我认为我的问题是我不知道在multiDataField模板中使用什么name属性.有什么建议吗?

Where multiDataField is this template. But it doesn't bind the dynamic fields properly and throws an invalid validation error on fields. I think my problem is I don't know what name attributes to use in my multiDataField template. Any advice?

推荐答案

您不需要任何客户数据绑定器.支持具有复杂对象的列表,而无需任何其他绑定注册.

You don't need any customer databinder. Lists with complex objects are supported without any additional binding registration.

在视图中,您可以使用@repeat助手,而在控制器中,您已经做得很好.

In the view you can use the @repeat Helper and in the controller you are already doing it well.

这里有一个有关播放和表单的完整示例,或直接在 TypeSafe

Here you have a complete example about Play and Forms, or directly in TypeSafe

编辑

在重复块中,csvField是列表中每个Form对象的实例.然后,您将需要添加视图所需的所有HTML元素.例如(简化为不带Bootstrap):

Inside the repeat block, csvField is an instance of every Form object in your List. Then you will need to add all the HTML elements you need for your view. For example (simplified without Bootstrap):

@helper.repeat(csvForm("fields"), min = 1) { csvField =>
    Name: <input type="text" name='@csvField("name").name' value='@csvField("name").value'>
    Type: <input type="text" name='@csvField("type").name' value='@csvField("type").value'>
}

您可以找到一个更完整的示例,其中包含提供的示例播放2.2.x .要在2.3.x中进行编译,可能需要进行一些更改,并且不使用Bootstrap 3.x,但是逻辑是相同的.

You can find a more complete example with the samples provide in Play 2.2.x. To compile it in 2.3.x maybe something need to be changed a bit and is not using Bootstrap 3.x, but the logic is the same.

编辑(2)

如果要向视图中动态添加 元素,则需要注意的是,在添加新元素时,应设置正确的数组编号.为此,您将需要使用JQuery:

If you want to add dynamically elements to the view, you will need to take care that when a new element is added, the right array number is set. For that you will need to use JQuery:

$('.addCSVField').click(function() {
    var CSVFields = $(this).parents('.CSVField');
    var template = $('.CSVField_template', CSVFields);
    template.before('<div class="clearfix CSVField">' + template.html() + '</div>');
    renumber();
})

$('.removeCSVField').click(function() {
    $(this).parents('.CSVField').remove();
    renumber(); 
})  

var renumber = function() {
    $('.CSVField').each(function(i) {
        $('input', this).each(function() {
            $(this).attr('name', $(this).attr('name').replace(/fields\[.+?\]/g, 'fields[' + i + ']'));
        })
    })
}

然后您需要将HTML/Scala代码更改为类似的内容:

And then you will need to change your HTML/Scala code to something like that:

@fieldGroup(field: Field, className: String = "CSVField") = {
    <div class="well @className">
        <a class="removeCSVField btn danger pull-right">Remove this field</a>
        Name: <input type="text" name='@field("name").name' value='@field("name").value'>
        Type: <input type="text" name='@field("type").name' value='@field("type").value'>
    </div>
}   

@repeat(csvForm("fields")) { csvField =>
    @fieldGroup(csvField)
}

@**
 * Keep an hidden block that will be used as template for Javascript copy code
 **@
@fieldGroup(csvForm("fields[x]"),className = "CSVField_template")   
<a class="addCSVField btn success">Add another field</a>

并添加CSS样式.CSVField_template{display: none;}

我没有测试任何一个,因此它可能无法编译.但是,我只是遵循了与

I did not test any of that, so it may not compile. However, I just followed a similar apporach as in the Forms example (play 2.2.x

这篇关于播放框架-为动态字段注册自定义DataBinder的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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