Knockout.js js将JSON对象映射到Javascript对象

Knockout.js js将JSON对象映射到Javascript对象,knockout.js,knockout-mapping-plugin,Knockout.js,Knockout Mapping Plugin,我无法将从服务器接收的Json对象映射到预定义的Javascript对象,该对象包含绑定中使用的所有必要函数 Javascript代码如下所示 function Person(FirstName, LastName, Friends) { var self = this; self.FirstName = ko.observable(FirstName); self.LastName = ko.observable(LastName); self.FullName

我无法将从服务器接收的Json对象映射到预定义的Javascript对象,该对象包含绑定中使用的所有必要函数

Javascript代码如下所示

function Person(FirstName, LastName, Friends) {
    var self = this;
    self.FirstName = ko.observable(FirstName);
    self.LastName = ko.observable(LastName);
    self.FullName = ko.computed(function () {
        return self.FirstName() + ' ' + self.LastName();
    })
    self.Friends = ko.observableArray(Friends);
    self.AddFriend = function () {
        self.Friends.push(new Person('new', 'friend'));
    };
    self.DeleteFriend = function (friend) {
        self.Friends.remove(friend);
    };      
}

var viewModel = new Person();

$(document).ready(function () {
    $.ajax({
        url: 'Home/GetPerson',
        dataType: 'json',
        type: 'GET',
        success: function (jsonResult) {
            viewModel = ko.mapping.fromJS(jsonResult);
            ko.applyBindings(viewModel);
        }
    });
});
HTML:

名字:

姓氏:

全名:

#朋友们:

@*最多允许5个朋友*@


@*定义应该如何呈现朋友*@ 名字: 姓氏: 全名:
获取初始数据的服务器端MVC代码如下所示:

    public ActionResult GetPerson()
    {
         Person person = new Person{FirstName = "My", LastName="Name",
                        Friends = new List<Person>
                        {
                             new Person{FirstName = "Friend", LastName="Number1"},
                             new Person{FirstName = "Friend", LastName="Number2"}
                        }
        };
        return Json(person, JsonRequestBehavior.AllowGet);
    }
public ActionResult GetPerson()
{
Person Person=newperson{FirstName=“My”,LastName=“Name”,
朋友=新列表
{
新人{FirstName=“Friend”,LastName=“Number1”},
新人{FirstName=“Friend”,LastName=“Number2”}
}
};
返回Json(person,JsonRequestBehavior.AllowGet);
}
我正在尝试使用映射插件将Json加载到我的Javascript对象中,以便绑定(add函数和Friend对象上的计算属性)的所有内容都可用

当我使用映射插件时,它似乎不起作用。 使用插件时,AddFriend方法在绑定期间不可用。
是否可以使用映射插件填充JavaScript Person对象,或者所有操作都必须手动完成?

您可以查看如何将映射选项传递给映射插件,特别是所述的
创建
回调

比如:

var mapping = {
    create: function(options) {
        var person = options.data,
            friends = ko.utils.arrayMap(person.Friends, function(friend) {
               return new Person(friend.FirstName, friend.LastName);   
            });

        return new Person(person.FirstName, person.LastName, friends);
    }
};
样本:

但是,在这种情况下,映射插件并不能提供很多功能,您只需自己调用Person构造函数并将Friends数组映射到构造函数中的Person对象即可,如下所示:


HTML中的另一个注意事项是:确保对于包含内容的元素,指定起始和结束标记(
span
按钮
在代码中不是这样)。如果您没有正确指定,KO将遇到问题。

非常感谢!你的回答清楚地说明了映射是如何工作的。Ryan,我一直在想,一旦你开始构建自己的构造器(比如你的“你没有从映射插件中获得很多功能”的评论),映射插件的效用是什么。当我开始使用构造函数时,我是否走错了路?如果我不使用构造函数,我不知道如何最好地处理将映射数据附加到用户输入的数据。有了构造器,我可以处理用户输入、检查错误、安全性等。我只是在使用knockout,希望走正确的路。想法?如果你想要最好的控制,那么我觉得自己使用构造函数是最好的方法。映射插件的
create
回调确实允许您在不同级别添加自己的属性,但我觉得它从来没有这么干净。当您只想将结构转换为可观察对象而不编写太多真实的客户端sie代码时,映射插件非常棒。仅供参考,我刚刚发现淘汰教程还建议手动映射到您自己的对象以获得更多控制(请参见步骤2):
var mapping = {
    create: function(options) {
        var person = options.data,
            friends = ko.utils.arrayMap(person.Friends, function(friend) {
               return new Person(friend.FirstName, friend.LastName);   
            });

        return new Person(person.FirstName, person.LastName, friends);
    }
};