淘汰简单对象映射

时间:2013-07-15 12:44:09

标签: asp.net-mvc knockout.js

我有一个像这样的简单MVC模型:

public class User
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string MobileNumber { get; set; }
    public string EmailAddress { get; set; }
}

我想在knockout viewmodel中映射此类型的一个对象以填充它:

var UserViewModel = function () {
    var self = this;
    self.user = ko.mapping.fromJS({});
    $.getJSON("/UserManagement/CreateEmptyUser", function (data) {
        ko.mapping.fromJS(data, self.user);
    });
    self.createUser = function (data, eventArgs) {
        var user = data;
        $.ajax({
            type: "post",
            contentType: "application/json",
            data: ko.toJSON(user),
            url: "@Url.Action("CreateUser")",
            success: function () {
                window.location = "@Url.Action("AddNew")";
            }
        });
    };
};

我遇到的问题是我不知道如何映射任何单个对象。我尝试过使用

self.user = ko.mapping.fromJS([]);
$.getJSON("/UserManagement/CreateEmptyUser", function (data) {
        ko.mapping.fromJS(data,{}, self.user);
    });

用于数组并尝试在索引0处提取元素,我认为可行的另一个解决方案是第二个注释块中的那个。我在谷歌上找到的所有东西都让我映射整个数组,但没有简单的对象映射。有没有正确的方法来做到这一点?我想保持模型分离,而不是在javascript中手动描述它的属性。

谢谢, 亚历克斯巴拉克

3 个答案:

答案 0 :(得分:3)

我认为您的问题是您正在使用方法映射来实例化您的视图模型,这将不会给它任何属性,因此当您尝试在JSON调用之后映射数据时,self.user上没有属性填充。使用您想要的属性创建用户对象,或者首先使用mapping.fromJS创建viewmodel:

self.user = { FirstName: ko.observable(''), etc... }

并保留您的地图线,或

self.user;
$.getJSON("/UserManagement/CreateEmptyUser", function (data) {
    self.user = ko.mapping.fromJS(data);
}

答案 1 :(得分:0)

我继续工作并检查这个,我在开始时找到了我想要的解决方案。这个想法是使用@Paul Manzotti的建议,

self.user;
$.getJSON("/UserManagement/CreateEmptyUser", function (data) {
    self.user = ko.mapping.fromJS(data);
}

但将self.user;替换为self.user={};

self.user = ko.mapping.fromJS(data)

ko.mapping.fromJS(data,{},self.user);

如果使用此方法,则无需在viewmodel中手动声明每个对象的属性。希望这对那些偶然遇到同样问题的人有用。

答案 2 :(得分:0)

如果你所讨论的viewModel本身需要是一个observable,那么我发现使用映射来返回一个可观察的数组,就像OP提到的那样,然后返回该数组中的第一个项目。这对于返回ajax中的一个对象也很有用,然后您希望将其推送到现有的observableArray。 我有一个辅助功能:

koMappingUsingArray = function (jsObject, mapping) {
    var observableObjectArray = ko.observableArray();
    var objectArray = new Array(jsObject);
    ko.mapping.fromJS(objectArray, mapping, observableObjectArray);

    return observableObjectArray()[0];
};

然后将其称为:

    self.myObject = ko.observable();

    $.ajax({
        type: "POST",
        url: "....",
        data: ko.mapping.toJSON(???),
        contentType: "application/json; charset=utf-8",
        success: function (returnedObject) {
            self.myObject (koMappingUsingArray(returnedObject));
        });