KnockoutJS - 打印迭代索引作为输入名称

时间:2014-08-19 14:26:57

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

我正在尝试与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控制器方法也没有填充值。

2 个答案:

答案 0 :(得分:2)

您缺少},可能会收到有关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}'

答案 1 :(得分:0)

<强>解决方案:

为“non-Knockout”元素添加引号并使用$ 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>