我们如何使用 thymeleaf 绑定对象列表的列表 [英] how we can bind a list of a list of object using thymeleaf

查看:162
本文介绍了我们如何使用 thymeleaf 绑定对象列表的列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个表单,用户可以在其中添加任意数量的 Table 对象,该表单还可以包含任意数量的 Columns 对象(例如构建表格在 SQL 中..我试过下面的代码,但没有任何作用,当我试图绑定两个列表时,表单不再出现.

控制器

@ModelAttribute("page")公共页面 getTable() {TableColumn 列 = new TableColumn();列表列 = 新的 ArrayList();列.添加(列);表表=新表();table.setColumns(列);列表<表格>表 = 新的 ArrayList();表.添加(表);页面页面=新页面();page.setTables(tables);返回页;}@GetMapping("/scriptsqlgenerator")public String viewForm(@ModelAttribute("page") Page page) {返回ScriptSqlNext";}@PostMapping("/scriptsqlgenerator")public String generateScript(@ModelAttribute("page") Page page) {page.tables.forEach((t) ->{System.out.println(t.getName());t.getColumns().forEach((c) -> {System.out.println(c.getName());System.out.println(c.getType());System.out.println(c.getIndex());System.out.println(c.getNotnull());});});}

HTML

<a class="list-group-item list-group-item-action" data-toggle="collapse" data-target="#target1">创建表</a><div id="target1" class="collapse" style="margin: 30px;"><div id="tablelist"><div class="form-inline itemtable" th:each="table, itemStat :${page.tables}"><div class="form-group mb-2 d-none"><input th:field="*{tables[__${itemStat.index}__].id}" type="text" class="form-control">

<div class="form-group mb-2"><input th:field="*{tables[__${itemStat.index}__].name}" type="text" class="form-control" placeholder="表名">

<input type="button" class="btn btn-danger mb-2 ml-2" onclick="addRow()" value="添加列"><div class="table-responsive"><table class="table table-bordered"><头><tr><th scope="col" class="d-none">Id</th><th scope="col">列名</th><th scope="col">Type</th><th scope="col">Index</th><th scope="col">Null</th></tr></thead><tbody id="列列表"><tr class="item" th:each="column,status :${table.columns}"><td><input th:field="*{tables[__${itemStat.index}__].columns[__${status.index}__].name}" type="text" class="form-控制"需要></td><td><select th:field="*{tables[__${itemStat.index}__].columns[__${status.index}__].type}" id="inputState" class="form-控制"需要>

<button class="btn btn-danger mb-2 text-center" type="button" id="addTable" style="margin-top: 30px;">添加表格</button>

<div class="text-center"><button type="submit" class="btn btn-outline-danger btn-lg" style="margin-顶部:50px;">生成文件</button>

</表单>

对于 JS 部分,我使用了一些代码来实现 addRow() 方法,该方法将向表中添加更多列和 addTable() 方法会添加另一个 Table 对象,但对我的情况没有任何作用

这是我的观点:*请任何人帮我解决..我真的需要它.. *

解决方案

你的方法没问题.但是您需要解决一些问题.

getTable 方法中,您正在为tablescolumns 设置空列表.所以在视图层中没有什么可以迭代来显示表单的.更改为:

@ModelAttribute("page")公共页面 getTable() {列 column = new Column();列表<列>列 = 新的 ArrayList();列.添加(列);表表=新表();table.setColumns(列);列表<表格>表 = 新的 ArrayList();表.添加(表);页面页面=新页面();page.setTables(tables);返回页;}

th:field="*{tables[__${i.index}__].name" 添加缺少的 } 并关闭此 input 标签.


注意:我不确定您想如何处理三个 select 输入.我测试了省略它们,意思是只保留 Column idname 在表单中,在这种情况下数据绑定没有任何问题.

我也没有检查你的 JS,因为你已经提到你还没有测试过.

建议:
我看到您正在从 POST 处理程序返回视图名称.看看维基百科上的以下文章.

发布/重定向/获取

I have a form where the user can add as much as he want of Table object that also can contains as much as he want of Columns object (like building tables in SQL).. I've tried the code bellow but nothing works and the form dosnt appear anymore when I've tried to bind the two lists.

Controller

@ModelAttribute("page")
    public Page getTable() {
         TableColumn column = new TableColumn();
            List<TableColumn> columns = new ArrayList<>();
            columns.add(column);

            Table table = new Table();
            table.setColumns(columns);

            List<Table> tables = new ArrayList<>();
            tables.add(table);

            Page page = new Page();
            page.setTables(tables);
        return page;
    }


    @GetMapping("/scriptsqlgenerator")
    public String viewForm(@ModelAttribute("page") Page page) {
        return "ScriptSqlNext";
    }

    @PostMapping("/scriptsqlgenerator")
    public String generateScript(@ModelAttribute("page") Page page) {
    page.tables.forEach((t) ->{
    System.out.println(t.getName());
        t.getColumns().forEach((c) -> {
        System.out.println(c.getName());
        System.out.println(c.getType());
        System.out.println(c.getIndex());
        System.out.println(c.getNotnull());
        });
    });
    }

HTML

<form th:object="${page}" class="list-group" th:action="@{/filegenerated}" method="get">
<a class="list-group-item list-group-item-action" data-toggle="collapse" data-target="#target1"> Create Table </a>
    <div id="target1" class="collapse" style="margin: 30px;">
        <div id="tablelist">
            <div class="form-inline itemtable" th:each="table, itemStat :${page.tables}">
                <div class="form-group mb-2 d-none">
                   <input th:field="*{tables[__${itemStat.index}__].id}" type="text" class="form-control">
                </div>
                <div class="form-group mb-2">
                    <input th:field="*{tables[__${itemStat.index}__].name}" type="text" class="form-control" placeholder="Table name">
                </div>
                <input type="button" class="btn btn-danger mb-2 ml-2" onclick="addRow()" value="Add column">
                <div class="table-responsive">
                    <table class="table table-bordered">
                        <thead>
                        <tr>
                            <th scope="col" class="d-none">Id</th>
                            <th scope="col">Column Name</th>
                            <th scope="col">Type</th>
                            <th scope="col">Index</th>
                            <th scope="col">Null</th>
                        </tr>
                        </thead>
                        <tbody id="columnlist">
                        <tr class="item" th:each="column,status : 
                            ${table.columns}">
                            <td><input th:field="*{tables[__${itemStat.index}__].columns[__${status.index}__].name}" type="text" class="form-control" required></td>
                            <td><select th:field="*{tables[__${itemStat.index}__].columns[__${status.index}__].type}" id="inputState" class="form-control" required>
                                <option value="" selected 
                                 disabled>Choose</option>
                                <option th:value="${type}">int</option>
                                <option th:value="${type}">varchar</option>
                                </select>
                            </td>
                            <td><select th:field="*{tables[__${itemStat.index}__].columns[__${status.index}__].index}" id="inputState" class="form-control" required>
                                <option value="" selected 
                                 disabled>Choose</option>
                                <option th:value="${index}">on</option>
                                <option th:value="${index}">off</option>
                                </select>
                            </td>
                            <td><select th:field="*{tables[__${itemStat.index}__].columns[__${status.index}__].notnull}" id="inputState" class="form-control" required>
                                <option value="" selected 
                                 disabled>Choose</option>
                                <option th:value="${notnull}">on</option>
                                <option th:value="${notnull}">off</option>
                                </select>
                            </td>
                        </tr>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    <button class="btn btn-danger mb-2 text-center" type="button" id="addTable" style="margin-top: 30px;">Add table</button>
</div>

<div class="text-center">
    <button type="submit" class="btn btn-outline-danger btn-lg" style="margin- 
     top: 50px;">Generate File</button>
</div>
</form>

For the JS part I was using some codes to implement the addRow() method which will add more Columns to the Table and addTable() method that would add another Table object, but nothing was working for my case

This is my view is looking like: *PLEASE CAN ANYONE HELP ME TO SOLVE THAT .. I REALLY NEED IT .... *

解决方案

Your approach is okay. But you need to fix a few things.

In the getTable method, you are setting empty lists for tables and columns. So there is nothing to iterate over in the view layer to show the form. Change to:

@ModelAttribute("page")
public Page getTable() {
    Column column = new Column();
    List<Column> columns = new ArrayList<>();
    columns.add(column);

    Table table = new Table();
    table.setColumns(columns);

    List<Table> tables = new ArrayList<>();
    tables.add(table);

    Page page = new Page();
    page.setTables(tables);

    return page;
}

And

Add missing } for th:field="*{tables[__${i.index}__].name" and close this input tag.


NOTE: I am not sure how you wanted to handle the three select inputs. I tested omitting them, meaning, keeping only Column id and name in the form, data bind without any issue in that case.

Also I didn't check your JS, as you have mentioned that you haven't tested it yet.

Suggestions:
I see you are returning a view name from your POST handler. Take a look at the following article on Wikipedia.

Post/Redirect/Get

这篇关于我们如何使用 thymeleaf 绑定对象列表的列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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