Checkbox 值在 false 时不绑定到对象中?

问题描述 投票:0回答:4

我使用 ModelAttribute 在 Spring Web 应用程序中绑定对象。

一旦我注意到,如果一个对象的布尔值 A 为真,如果我们取消选中 A 的复选框,它的值将不会更新。

例如,我有一个具有属性“active”= true 的 Lesson 对象。 在“编辑课程”视图中,我创建了一个绑定到“活动”的复选框。如果复选框被选中(绑定对象反映了变化),一切都会很好,但如果我们取消选中复选框,对象课程将不会改变。

进一步研究告诉我这是因为复选框值可能不会被浏览器提交(这是 HTML 的设计)。所以我必须使用丑陋的

request.getParameter
来检查是否设置了值。

我刚刚遇到 这个问题,我看到 asp.net mvc 提供了一种更优雅地解决它的方法。我认为 Spring 必须提供类似的东西。有谁知道怎么做?

以下是我的代码:

控制器代码:

    @RequestMapping(value="/test", method = RequestMethod.POST)
    public String processEditLesson(@Valid Lesson lesson, BindingResult bindingResult, Model model) {
        System.out.println("Lesson is active: " + lesson.isActive()); // still "true" even if the checkbox is unset

        // Current work-around
        String isActive = request.getParameter("active");
        if (StringUtils.isNotNullOrEmpty(isActive)) {
            lesson.setActive(true);
        } else {
            lesson.setActive(false);
        }
        ...
    }

查看代码:

<form id="lesson" class="EditorForm" action="${rc.getContextUrl('/test.html')}" method="post" >

    <fieldset>
        <legend><@spring.message code="lesson.edit"/></legend>
        <@spring.formHiddenInput "lesson.id" />
        <@spring.formHiddenInput "lesson.studio.id" />

        <div class="Entry">
            <label for="name"><@spring.message code="lesson.message"/></label>
            <@spring.formInput "lesson.message" />
            <span class="ErrorMessage"><@spring.showErrors "<br/>" /></span>
        </div>

        <input type="checkbox" name="active" checked="checked" />
        <label for="active">${rc.getMessage('lesson.active')}</label>

        <input type="submit" value="<@spring.message code='common.update' />" />
    </fieldset>
</form>
java html spring spring-mvc freemarker
4个回答
25
投票

Spring 有一个内置的解决方法。

只需将这个额外的隐藏字段添加到表单中:

<input type="hidden" value="on" name="_active"/>

带前导下划线的参数是某种标记,表示存在同名但没有下划线的复选框参数。

如果只提交

lesson.active
,Spring现在应该将
_active=on
设置为false。


3
投票

我认为你应该使用 springframework 标签——你为什么要使用纯 html?如果您的视图是 JSP 页面,只需导入:

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

然后你可以使用:

<form:checkbox path="path" label="label" />

处理问题。


1
投票

您可以使用 spring 框架标签,它会自动将您选择的值设置为 bean 类,然后很容易在您的控制器类中获取它的值。

在你需要把你的 bean 变量名放在路径上

要使用它,您需要为您的表单提供命令名称,并使用该命令名称将您的 bean 对象绑定到该 jsp

model.addAttribute("command name", bean object) 在你的控制器中使用它来绑定对象。


0
投票

这是对@Ralph 上面提供的答案中更复杂的嵌套 DTO 的附加增强功能,我可以通过添加

_
来确认,如下面的示例对我来说效果很好(所有其他示例都失败了):

   <input type="hidden" value="on" th:name="
${'_content['+contStat.index+'].something.someBooleanCheckbox'}"/>

更复杂的例子:

 <input class="form-check-input" th:checked="${cont.something != null && 
 cont.something.someBooleanCheckbox != null ? 
   cont.something.someBooleanCheckbox :
   false}" 
   th:name="{'content['+contStat.index+'].something.someBooleanCheckbox'}" 
   type="checkbox" 
   th:id="${'content['+contStat.index+'].something.someBooleanCheckbox'}">

   
© www.soinside.com 2019 - 2024. All rights reserved.