【问题标题】:Thymeleaf dynamic datatype for form表单的 Thymeleaf 动态数据类型
【发布时间】:2016-11-14 13:38:43
【问题描述】:

我有一个 HashMap,为某些文档提供数据:

 Key   |   Value
 ----------------
 Name  |   test1
 Type  |   type1
 ...

没有指定行数,键和值一开始都是字符串。

现在我想编辑这个动态数据。因此我创建了这个模板:

<form action="#" th:action="@{/documents/{id}(id=${doc_id})}" th:object="${properties}" method="post">
    <h1 th:text="${document_h1_text}">Documents</h1>
    <table class="table table-striped">
        <tr>
            <th>Property</th>
            <th>Value</th>
        </tr>
        <tr th:each="property : ${document_properties}">
            <td th:text="${property.key}">Property</td>
            <td>
                <input name="${property.key}" th:value="${property.value}" />
            </td>
        </tr>
    </table>
    <button type="submit" class="btn btn-default">Submit</button>
</form>

document_propertiesHashMap&lt;String,String&gt; 相关

当我使用此网络服务获取此网络服务时,它工作正常

@RequestMapping(path = "documents/{doc_id}", method = RequestMethod.GET)
public String document(@PathVariable long doc_id, Model model) { ... }

现在我想在前端编辑这个输出并提交更改:

@PostMapping("documents/{doc_id}")
public String editDocument(@PathVariable long doc_id, @ModelAttribute HashMap<String, String> properties,Model model) { ... }

不幸的是,当我通过单击“提交”按钮调用它时,HashMap properties 是空的。你们中有人知道如何解决这个问题吗?仅供参考:我故意选择不在这里使用传统的类绑定。原因是我想要一个动态的解决方案,使用任意类。

【问题讨论】:

    标签: java spring forms hashmap thymeleaf


    【解决方案1】:
    1. 您至少需要一个围绕 Map 的包装器(我认为您不能按照自己希望的方式直接绑定到 Map)。
    2. 如果可能,您应该始终使用 th:field 而不是 th:name 和 th:value。

    这里有一个简单的例子,应该可以按照你想要的方式工作。

    包装器

    public class MapWrapper {
        private Map<String, String> map = new HashMap<>();
    
        public Map<String, String> getMap() {
            return map;
        }
    
        public void setMap(Map<String, String> map) {
            this.map = map;
        }
    }
    

    控制器

    @Controller
    public class MapController {
        @GetMapping("map.html")
        public String get(Map<String, Object> model) throws Exception {
            MapWrapper wrapper = new MapWrapper();
            wrapper.getMap().put("1", "One");
            wrapper.getMap().put("2", "Two");
            wrapper.getMap().put("3", "Three");
    
            model.put("wrapper", wrapper);
            return "map";
        }
    
        @PostMapping("map.html")
        public String post(Map<String, Object> model, @ModelAttribute("wrapper") MapWrapper wrapper) throws Exception {
            return "map";
        }
    }
    

    表格

    <form action="map.html" th:object="${wrapper}" method="post">
        <table class="table table-striped">
            <tr>
                <th>Property</th>
                <th>Value</th>
            </tr>
    
            <tr th:each="key : ${wrapper.map.keySet()}">
                <td th:text="${key}" />
                <td>
                    <input th:field="*{map[__${key}__]}" />
                </td>
            </tr>
        </table>
    
        <button type="submit" class="btn btn-default">Submit</button>
    </form>
    

    【讨论】:

      【解决方案2】:

      它有过高的支持对象,似乎不是一个好方法,我认为我们需要一些通用模式:

      public class GenericEntity {
      protected Map<String, Object> properties = new LinkedHashMap<String, Object>(); 
      //setter getter
      }
      

      entity extends GenericEntity 并在控制器中

        <tr th:each=" key : ${wrapper.map.keySet()}">
             <td th:text="${key}" />
             <td>
              <input th:field="*{properties[__${key}__]}" />
             </td>
        </tr>
      

      但是你应该找到一种在超类中设置属性映射的方法,它是硬编码的,另一种方法可能是为 thymleafe v3 写下自定义方言。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-05-17
        • 1970-01-01
        • 2014-08-06
        • 1970-01-01
        • 2023-03-28
        • 1970-01-01
        • 2016-01-12
        • 2018-12-16
        相关资源
        最近更新 更多