3

我正在使用 MVC4 并尝试使用它的 knockoutjs 库。如果我使用传统的提交单击而不使用 Knockoutjs 库,则表单会将数据提交给控制器。我正在使用 knockoutjs 映射插件将视图模型从服务器转换为创建客户端视图模型,然后尝试在客户端扩展它。

  • 要从服务器端转换为客户端 vm,我正在使用ko.mapping.fromJS(model);
  • 要将数据发布回服务器,我在ko.toJSON(model)使用 jQuery 通过 ajax 发送时将其转换回来。

我在服务器上收到的数据为空。另外,当我登录ko.toJSON(model)控制台时,我得到以下信息:

{
    "FirstName": "foo",
    "LastName": "foo1",
    "Address": "United Kingdom",
    "Age": 22,
    "__ko_mapping__": {
        "ignore": [],
        "include": ["_destroy"],
        "copy": [],
        "observe": [],
        "mappedProperties": {
            "FirstName": true,
            "LastName": true,
            "Address": true,
            "Age": true
        },
        "copiedProperties": {}
    }
}

在将 js 对象转换回 json 格式以将数据发送到服务器时,我似乎做得不对。以下是我的所有代码:

控制器代码:

public class PersonController : Controller
    {
        PersonViewModel viewModel = new PersonViewModel();
        //
        // GET: /Person/
        [HttpGet]
        public ActionResult Index()
        {

            return View(viewModel);
        }

        [HttpPost]
        public ActionResult Index(PersonViewModel viewModel)
        {
            if (ModelState.IsValid)
            {

            }
            return View(viewModel);
        }
//
    // GET: /Person/LoadData/

    public ActionResult LoadData()
    {
        viewModel = new PersonViewModel() { FirstName = "foo", LastName = "foo1", Age = 22, Address = "United Kingdom" };
        return Json(viewModel, JsonRequestBehavior.AllowGet);
    }
}

服务器上的视图模型:

 public class PersonViewModel
    {
        [Required]
        public string FirstName { get; set; }
        [Required]        
        public string LastName { get; set; }
        [Required]
        public string Address { get; set; }
        [Required]
        public int Age { get; set; }
    }

客户端的 ViewModel - JavaScript:

var Person = function () {
    var self = this;


    self.SetupKOBindings = function () {
        var source = null;
        this.GetViewModelFromServer = function () {
            $.ajax(
                {
                    url: "/Person/LoadData",
                    type: "GET",
                    async: false
                }).
            success(function (data) {
                source = data;
            });
        }();
        return ko.mapping.fromJS(source);
    };

    self.ViewModel = function () {
        this.model = self.SetupKOBindings();

        this.model.Save = function () {
            console.log(ko.toJSON(model));
            $.ajax(
               {
                   url: "/Person/Index",
                   type: "POST",
                   data: ko.toJSON(model),
                   async: true
               }).
           success(function (data) {

           });
        }

        return this.model;
    };

    self.ApplyKOBindings = function (vm) {
        ko.applyBindings(vm);
    };

    return this;
};

$(function () {
    var PersonPage = Person();
    var viewModel = PersonPage.ViewModel();
    PersonPage.ApplyKOBindings(viewModel);
});

服务器上 .cshtml 中的 HTML:

<form action="" method="post">
        <div>
            First Name:
            @Html.TextBoxFor(model => model.FirstName, new { data_bind = "value: FirstName,valueUpdate:['afterkeydown','propertychange','input']" })<br />
        </div>
        <div>
            Last Name:
                    @Html.TextBoxFor(model => model.LastName, new { data_bind = "value: LastName,valueUpdate:['afterkeydown','propertychange','input']" })<br />
        </div>
        <div>
            Address:
                    @Html.TextBoxFor(model => model.Address, new { data_bind = "value: Address" })<br />
        </div>
        <div>
            Age:
                    @Html.TextBoxFor(model => model.Age, new { data_bind = "value: Age" })<br />
        </div>
        <input type="submit" value="Save" data-bind="click: Save"/>

    </form>
4

3 回答 3

6

如果您使用的是映射插件,您应该使用ko.mapping.toJSON(model)而不是ko.toJSON(model)因为这会删除“ ko_mapping ”属性。

但是您的主要问题是,因为您正在发送 JSON,所以您需要在请求中告知您正在发送 JSON,否则 ASP.NET MVC 无法解析服务器端的请求。为此,您需要将contentType属性设置为"application/json"

所以下面的$.ajax调用应该有效:

$.ajax({
    url: "/Person/Index",
    type: "POST",
    data: ko.mapping.toJSON(model),
    async: true,
    contentType: "application/json"
}).success(function (data) {

});
于 2013-10-08T13:27:22.483 回答
0

如果你使用 ko.mapping.fromJS 将 js 对象转换为带有 observables 的对象。

您必须使用 ko.mapping.toJS 将其转换回 js 对象。

我希望它有所帮助。

于 2013-10-08T13:08:40.387 回答
0

您的控制器不知道通过什么变量发送,因此不知道要绑定到什么。

改变:

this.model.Save = function () {
            console.log(ko.toJSON(model));
            $.ajax(
               {
                   url: "/Person/Index",
                   type: "POST",
                   data: ko.toJSON(model),
                   async: true
               }).
           success(function (data) {

           });
        }

至:

this.model.Save = function () {
            console.log(ko.toJSON(model));
            $.ajax(
               {
                   url: "/Person/Index",
                   type: "POST",
                   data: { viewModel: ko.toJSON(model) },
                   async: true
               }).
           success(function (data) {

           });
        }

更新(尝试的东西):

var data = {
    FirstName: model.FirstName || 'Test'
};

$.ajax({
           url: "/Person/Index",
           type: "POST",
           data: ko.toJSON(data),
           async: true
       }).
       success(function (data) {
  });
于 2013-10-08T13:14:06.927 回答