【问题标题】:How do you model form changes under Spring MVC?您如何在 Spring MVC 下对表单更改进行建模?
【发布时间】:2011-01-05 02:08:42
【问题描述】:

假设您正在使用 Spring MVC 的 SimpleFormController 版本 2.5.6 为水果供应商编写网页。在这个页面上,供应商可以做一些简单的事情,比如改变他们的名字或地址。他们还可以根据包含当前库存选择的下拉列表更改其库存。

当此下拉列表选择更改时,整个表单会更改以匹配所选内容的清单。因此,一种股票选择可能有香蕉和梨,另一种可能有甜瓜、蓝莓和葡萄柚。

在每个库存选择中都有一个需要传播回数据库的输入字段,为了这个示例,假设用户输入了水果的数量。

在数据库中建模的方式是将每个 Stock 名称存储在一个表中,该表与每个 Stock 的内容存在一对多的关系,这将是本示例中的水果类型。那么水果的类型与供应商选择的数量有一对多的关系。库存名称和每个库存中的水果类型存储在数据库中,用户不可更改,连接的水果数量表是可编辑的。

我的问题是,如何在 Spring MVC 中对上述表单进行建模?

我已经尝试覆盖isFormChangeRequestonFormChange 以促进表单更改,但我想我可能误解了这些方法的意图。当我下次发布页面时更改我的支持命令对象时,它会尝试将请求绑定到表单中,如果您调整 Stock 数组的大小(例如从 3 到 2,它将尝试绑定到第 3 个)值,即使它是空的)。

【问题讨论】:

    标签: model-view-controller spring forms web-applications spring-mvc


    【解决方案1】:

    我最终做的是在下拉列表中的选择更改时触发一个 JavaScript 事件。此 JavaScript(见下文)根据下拉列表的选择生成一个 URL,并使用 location.replace 转到新 URL,这会导致控制器生成一个新表单。

    使用此方法覆盖 isFormChangeRequest 和 onFormChange 使我能够避免由遗留的 post 数据引起的绑定错误。

    function changeUrl(selectionValue) {
        var param = getParams();
        param["dropdownselection"] = selectionValue;
        window.location.replace(getBaseUrl() + buildQueryString(param));
    }
    
    //taken from http://javascript.about.com/library/blqs1.htm
    function getParams() {
        var qsParm = new Array();
        var query = window.location.search.substring(1);
        var parms = query.split('&');
        for (var i = 0; i < parms.length; i++) {
            var pos = parms[i].indexOf('=');
            if (pos > 0) {
                var key = parms[i].substring(0,pos);
                var val = parms[i].substring(pos+1);
                qsParm[key] = val;
            }
        }
        return qsParm;
    }
    
    function getBaseUrl() {
        var url = document.location.toString();
        if (url.indexOf('?') != -1) {
            url = url.substring(0, url.indexOf('?'));
        }
        return url;
    }
    
    function buildQueryString(param) {
        var queryString = "?";
        for (var key in param) {
            queryString += key + "=" + param[key] + "&";
        }
        //remove last "&"
        return queryString.substring(0,queryString.length - 1);
    }
    

    【讨论】:

      【解决方案2】:

      如果您的不同库存数量有限,您可以为每个具有不同支持模型的库存使用不同的处理程序映射:

      @RequestMapping(params="stock=example1") ModelAndView handleExample1(@ModelAttribute("stock") ApplesOrangesPears stockObject)

      @RequestMapping(params="stock=example2") ModelAndView handleExample2(@ModelAttribute("stock") BananasPotatos stockObject)

      但我想情况并非如此,有很多不同的股票类型,而且它们是动态的。在这种情况下,您可以注册自定义属性编辑器 (@InitBinder),并动态确定库存支持对象的实际类型,然后进行验证,并显式转换为它或从它转换。

      【讨论】:

      • 我不确定我是否遵循您的回答。我不熟悉 Spring MVC 3.0 样式注释,所以我在第一部分和第二部分中遇到了麻烦,我不确定我是否理解自定义属性编辑器会提供什么好处。你能详细说明一下吗?谢谢。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-04
      • 1970-01-01
      • 1970-01-01
      • 2012-01-01
      • 2012-11-01
      相关资源
      最近更新 更多