使用knockout的MVC jquery验证为什么即使字段为空也会运行save方法

时间:2012-08-09 23:46:20

标签: jquery asp.net-mvc validation knockout.js jquery-validate

我有以下代码:

Index.cshtml:

    @using System.Web.Script.Serialization
@model MvcApplication3.ViewModels.PersonViewModel
<script src="../../Scripts/jquery.validate.min.js" type="text/javascript"></script>
<script src="../../Scripts/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
<script src="../../Scripts/jquery.unobtrusive-ajax.min.js" type="text/javascript"></script>
<script src="../../Scripts/knockout-2.1.0.js" type="text/javascript"></script>
    <!-- This is a *view* - HTML markup that defines the appearance of your UI -->
<form class="transferListEditor" data-bind="submit: save">

    <p>First name: <input class='required' data-bind="value: firstName, uniqueName: true" /></p>
    <p>Last name: <input class='required' data-bind="value: lastName, uniqueName: true" /></p>

    <table>
        <thead>
            <tr>
                <th>Name</th>
            </tr>
        </thead>
        <tbody data-bind="foreach: activities">
            <tr>
                <td><input data-bind="value: Name" /></td>
                <td><a href="#" data-bind="click: $root.removeActivity">Remove</a></td>
            </tr>    
        </tbody>
    </table>
    <button data-bind="click: addActivity">Add activity</button>
    <button type="submit">Submit</button>
</form>

<script type="text/javascript">

    var initialData = @Html.Raw(new JavaScriptSerializer().Serialize(Model));

    function activity(name) {
        var self = this;
        self.Name = name;
    }

    // This is a simple *viewmodel* - JavaScript that defines the data and behavior of your UI
    var viewModel = {
        firstName: ko.observable(initialData.Person.FirstName),
        lastName: ko.observable(initialData.Person.LastName),
        activities: ko.observableArray(initialData.Person.Activities),

        removeActivity : function(activity) {

            viewModel.activities.remove(activity);
        },

        addActivity : function() {
            viewModel.activities.push(new activity(""));
        },

        save: function() {

            $.ajax({
                type: "POST",
                url: "/Home/Index",
                data: ko.toJSON({ Person: viewModel }),
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function(data) {
                    $("#resultCount").html(data);
                }
            });
        }
    };

    // Activates knockout.js
    ko.applyBindings(viewModel);

    $("form").validate({ submitHandler: viewModel.save });
</script>

HomeController中:

    using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Ahb.Insite.HerdRegistration.WebUI;
using MvcApplication3.Models;
using MvcApplication3.ViewModels;

namespace MvcApplication3.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            var person = new Person {FirstName = "John", LastName = "Cool"};

            person.Activities = new List<Activity> { new Activity { Name = "Skiing" } };

            var personViewModel = new PersonViewModel  { Person = person };

            return View(personViewModel);
        }

        [HttpPost]
        public ActionResult Index(PersonViewModel personViewModel)
        {
            //Save it

            return View();
        }
    }
}

因此,当我单击“提交”时,如果它们为空,则会显示firstname和lastname所需的字段消息。问题是即使缺少必需的字段,仍然会调用viewModel上的save方法。

任何人都知道如何解决?

1 个答案:

答案 0 :(得分:2)

尝试删除表单上的data-bind="submit: save"

由于敲除绑定在jQuery验证绑定之前被绑定,它可能只是首先点击保存代码。

我注意到使用jQuery验证的example与knockout在表单元素上没有数据绑定。

更新:confirmed我可以通过在示例中添加data-bind属性来重现您的问题。