处理相同类型的多种形式 - 不可能?

时间:2012-08-08 07:47:18

标签: spring spring-mvc

考虑以下情况:

  1. 我的表单模型

    public class PersonForm {
        @NotNull
        private String name;
    
        /*usual getters and setters*/
    }
    
  2. 我的控制器:

    @Controller
    @SessionAttribute(types={ PersonForm.class })
    public class MyController {
    
        @RequestAttribute(...)
        public String render(final ModelMap map) {
            /* get list of info and for each info 
             * create a PersonForm and put it in the modelmap
             * under key p0, p1, p2, ..., pn
             */
        }
    
        public String submit(final ModelMap map,
                             @Valid final PersonForm form,
                             final BindingResult result) {
    
            if (result.hasErrors()) {
                // return to page
            } else {
                // do necessary logic and proceed to next page
            }
        }
    }
    
  3. 最后是我的JSP视图

    ...
    <c:forEach ...>
        <form:form commandName="p${counter}">
            ... other form:elements and submit button goes here
        </form:form>
    </c:forEach>
    ...
    
  4. 正如您所看到的,我正在尝试处理同一类类型的多种形式。提交工作 - 它让我接受提交(...)方法就好了,验证也是如此。但重新呈现页面并没有显示预期的错误消息!

    更糟糕的是 - 我检查了提交标题中传递的内容,并且没有任何表明提交的表单,因此无法区分另一个表单。这使我相信不可能有多种形式的同一类型......

    除了Ajax之外,还有其他方法吗?

    非常感谢。

2 个答案:

答案 0 :(得分:2)

我设法让这个'黑客'上班。正如 jelies 所建议的那样,所有这些都归于他。

简单来说,概念是使用传统的<c:forEach>构造预先填充您的视图。棘手的部分是每当按下相应行的“提交”按钮时,必须将所有信息注入隐藏表格并强制提交给控制器。如果屏幕再次呈现并出现一些错误,则脚本必须负责将值注入相应的行,包括错误。


1)我的模特

    public class PersonForm {

        private String id;

        @NotNull
        private String name;

        /*usual getters and setters*/
    }

2)我的控制器

    @Controller
    @SessionAttribute(/* the hidden form name, the person list */)
    public class MyController {

        @RequestAttribute(...)
        public String render(final ModelMap map) {
            /* get list of info and for each info 
             * create a PersonForm and put it in the modelmap
             * under key p0, p1, p2, ..., pn
             */
        }

        public String submit(final ModelMap map,
                             @Valid final PersonForm form,
                             final BindingResult result) {

            if (result.hasErrors()) {
                // return to page
            } else {
                // do necessary logic and proceed to next page
            }
        }
    }

3)我的观点

    ...

    <form:form commandName="personForm" cssStyle="display: none;">
        <form:hidden path="id"/>
        <form:hidden path="name" />
        <form:errors path="name" cssStyle="display: none;" />
    </form:form>

    ...

    <c:forEach var="p" items="${pList}">
        <input type="text" id="${ p.id }Name" value="${ p.name }" />
        <!-- to be filled in IF the hidden form returns an error for 'name' -->
        <span id="${ p.id }nameErrorSpan"></span>
        <button type="button" value="Submit" onclick="injectValuesAndForceSubmit('${ p.id }');" />
    </c:forEach>

    ...

    <script type="text/javascript">

    injectValuesAndForceSubmit = function(id) {

        $('#id').val( id ); // fill in the hidden form's id
        $('#name').val( $('#'+id+'name').val() ); //fill in the hidden form's name

        $('#personForm').submit(); //submit!
    }



    $(document).ready(function() {

        var id = $('#id').val();    
        if (id.trim().length == 0) {
            //Empty. Nothing to do here as this is a simple render.
        } else {

            //The page seems to be returning from some sort of error ... pre-fill the respective row!
            $('#'+id+'name').val($('#name').val());
            var hiddenNameErrorSpan = $('#name.errors');
            if (hiddenNameErrorSpan) {
                $('#'+id+'nameErrorSpan').text(hiddenNameErrorSpan.html());
            }
        } //else
    }
    </script>

正如你所看到的那样,视图中有最毛茸茸的部分 - 希望它仍然可以证明对于那些(不幸)遇到与我相同情况的人来说是有用的。干杯!

答案 1 :(得分:0)

具有多种形式的恕我直言使事情变得过于复杂(或者至少是春天)。此外,您正在使用多个表单,但只会提交一个表单。

所以,我建议最简单的方法是使用一个独特的隐藏外部表单和人物属性。当按下其中一个按钮时,相应地填写表格的人物属性并提交。有了这个,你就可以实现典型的弹簧形式提交/验证。

也许这个解决方案需要使用JavaScript,但我不知道如何处理具有多种形式的spring-mvc,我总是试图避免它,因为之前的尝试不成功。