【问题标题】:KnockoutJS - Print iteration index as input nameKnockoutJS - 将迭代索引打印为输入名称
【发布时间】:2014-10-12 16:56:17
【问题描述】:

我正在尝试结合 Spring MVC 的 @ModelAttribute 绑定创建我的第一个 KnockoutJS 表单视图。

  • 数据通过 Ajax 加载并使用 KnockoutJS 填充
  • 通过 KnockoutJS 添加数据
  • 通过 Ajax 和 KnockoutJS 删除数据
  • 数据将通过普通的 POST 提交保存到 Spring MVC 控制器。

要将表单输入绑定到 Spring MVC 控制器,我需要来自 KnockoutJS 的迭代索引。所以我尝试了以下操作:

但是我的数据库中的值永远不会像我用data-bind='value: key' 绑定它们时那样绑定。你能帮我找出错误吗?

JSP:

<form:form modelAttribute="configurationHelper" action="/saveConfigurationList.htm" method="POST" id="configuration-form" class="form-inline">
    <tbody data-bind="foreach: configurations">
        <tr>
            <td>
                // this is working
                <input data-bind='value: key' class="form-control input-sm" type="text"/>
                // this is not working
                <input data-bind='attr:{value: key, name:configurationHelper.configurations[$index].key' class="form-control input-sm" type="text"/> 
            </td>
            <td>
                <a href='#' data-bind='click: $root.removeConfiguration' class="ordinary-tooltip" title='<spring:message code="general.delete"/>'>
                    <i class="fa fa-lg fa-trash-o "></i>
                </a>
            </td>
         </tr>
    </tbody>
</form:form>

模型视图:

function ConfigurationViewModel() {
    var self = this;
    self.configurations = ko.observableArray([]);

    self.loadConfigurations = function() {
        $.ajax({
            type : "POST",
            url : "/loadConfigurationList.htm",
            success : function(response) {
                var responseArray = JSON.parse(response);
                var mappedConfigurations = $.map(responseArray.configurations, function(configuration) {
                    return new Configuration(configuration);
                });
                self.configurations(mappedConfigurations);
            },
            error : function(e) {
                alert('Error: ' + e.status);
            }
        });
    }

    self.saveConfigurationList = function() {
        $("#configuration-form").submit();
    }

    self.addConfiguration = function() {
            self.configurations.push({
                id: 0,
                key: "",
                value: "",
        });
    };

    self.removeConfiguration = function(configuration) {
        if(confirm(springMessageGeneralDeleteReally)){
            $.ajax({
                type : "POST",
                url : "/deleteConfiguration.htm",
                data: {"configurationId": configuration.id},
                success : function(response) {
                    self.configurations.remove(configuration);
                },
                error : function(e) {
                    alert('Error: ' + e.status);
                }
            });
        }
    };
}


function Configuration(data) {
    this.id = ko.observable(data.id);
    this.key = ko.observable(data.key);
    this.value = ko.observable(data.value);
}

总结:

  • Knockout 应该只负责将值(使用 AJAX 加载)绑定到输入并显示正确的输入名称。 (将输入值绑定回 Spring MVC 控制器)
  • configurationHelper 是一个请求参数,不应打扰 Knockout。只能将configurationHelper.configurations的列表绑定到Spring MVC。

以下表单已正确绑定到 Spring MVC 控制器:

<form:form modelAttribute="configurationHelper" action="/leina16/configuration/saveConfigurationList.htm" method="POST" id="configuration-form" class="form-inline">
    <form:input path="configurations[0].key" class="form-control input-sm"/>
</form:form>

现在我想用 Knockout JS 扩展输入,所以我至少需要 data-bind 属性以及来自 Knockout 的 foreach: $index

<tbody data-bind="foreach: configurations">
    <input data-bind='attr:{value: key, name:"configurations[$index].key}' class="form-control input-sm" type="text"/>
</tbody>

但上面的片段既没有绑定到 Spring MVC 控制器方法,也没有填充值。

【问题讨论】:

    标签: javascript spring spring-mvc knockout.js modelattribute


    【解决方案1】:

    您缺少},并且可能收到有关 Knockout 无法解析绑定的错误。

    变化:

    'attr:{value: key, name:configurationHelper.configurations[$index].key'
    

    收件人:

    'attr:{value: key, name:configurationHelper.configurations[$index].key}'
    

    由于configurationHelper 是在foreach 循环之外定义的,因此您需要使用$parent or $root 来引用它:

    'attr:{value: key, name:$parent.configurationHelper.configurations[$index].key}'
    

    【讨论】:

    • @Tunguska 哎呀,忘了提一些重要的事情。我已经更新了我的答案。 :)
    • 谢谢 :) 但是我仍然面临这样的问题,即表单输入数据既没有绑定到 spring 控制器,也没有现有数据(通过 AJAX 加载)绑定到表单输入。我将添加一个简短的摘要以便更好地理解。
    【解决方案2】:

    解决方案:

    为“非敲除”元素添加引号并使用 $index() 函数。

    <tbody data-bind="foreach: configurations">
        <tr>
            <td>
                <input data-bind='attr:{value: key, name:"configurations["+$index()+"].key"}' class="form-control input-sm" type="text"/>
            </td>
    
         </tr>
     </tbody>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-07
      • 2015-02-27
      • 2014-11-10
      • 2022-12-06
      • 2020-02-19
      • 2014-12-14
      • 2023-02-09
      • 1970-01-01
      相关资源
      最近更新 更多