Knockout.js ko.mapping.toJS不处理子可观察数组属性

Knockout.js ko.mapping.toJS不处理子可观察数组属性,knockout.js,knockout-mapping-plugin,knockout-2.0,Knockout.js,Knockout Mapping Plugin,Knockout 2.0,当我在子属性标记上调用ko.mapping.toJS(这是一个observableArray)时,生成的JS对象被映射为[{},{},{}];知道为什么子属性的属性没有被映射吗 // Question sv.QuestionService = function () { var _saveQuestion = function (question, callback) { var tags = [ { Id: 1,

当我在子属性标记上调用ko.mapping.toJS(这是一个observableArray)时,生成的JS对象被映射为[{},{},{}];知道为什么子属性的属性没有被映射吗

// Question
sv.QuestionService = function () {
    var _saveQuestion = function (question, callback) {
        var tags = [
            {
                Id: 1,
                Name: "food"
            },
            {
                Id: 2,
                Name: "career"
            },
            {
                Id: 3,
                Name: "fax"
            }
        ];

        $.each(tags, function (index, item) {
            question.Tags.push({ Id: 1, Name: "food" });
        });

        console.log(question.Tags());

        $.ajax("/Interview/saveQuestion", {
            data: ko.mapping.toJSON(question),
            dataType: "json",
            type: "post",
            contentType: "application/json",
            success: callback
        });
    };


    return {
        saveQuestion: _saveQuestion
    };
}();

// Question view model
sv.QuestionViewModel = function (data) {
    var self = this;
    if (!data.QuestionType) {
        data.QuestionType = "Not Specified";
    }
    this.Tags = ko.observableArray([]);
    ko.mapping.fromJS(data, {}, this);
    this.QuestionStatus = ko.computed(function () {
        return this.IsApproved ? "Pending Interview Question" : "Approved Interview Question"
    }, this);

    this.TagsText(this.TagsText() || "None");
};

// C#
public class InterviewQuestionViewModel {
    public long Id { get; set; }
    public string Text { get; set; }
    public string QuestionType { get; set; }
    public long? QuestionTypeId { get; set; }
    public string RequestorName { get; set; }
    public bool IsAdminApproved { get; set; }
    public bool IsActive { get; set; }
    public string TagsText { get; set; }
    public List<Tag> Tags { get; set; }

    public InterviewQuestionViewModel() {
        Tags = new List<Tag>();
    }
}

public class Tag {
    [Description("tag_id")]
    public long Id { get; set; }

    [Description("tag_name")]
    public string Name { get; set; }

    public bool IsActive { get; set; }

    public Tag() {
        IsActive = false;
    }
}

// Approved Questions view model
sv.ApprovedQuestionListViewModel = function () {
    var self = this;
    this.questions = ko.observableArray([]);

    this.questionCount = ko.computed(function () {
        return this.questions().length;
    }, this);

    this.load = function () {
        sv.QuestionService.getApprovedQuestions(function (data) {
            var mapped = ko.utils.arrayMap(data, function (item) {
                return new sv.QuestionViewModel(item);
            });
            self.questions(mapped);
        });
    }.bind(this);
};
//问题
sv.QuestionService=函数(){
var\u saveQuestion=函数(问题,回调){
变量标记=[
{
Id:1,
名称:“食品”
},
{
Id:2,
姓名:“职业”
},
{
Id:3,
姓名:“传真”
}
];
$。每个(标记、功能(索引、项){
push({Id:1,名称:“food”});
});
log(question.Tags());
$.ajax(“/Interview/saveQuestion”{
数据:ko.mapping.toJSON(问题),
数据类型:“json”,
类型:“post”,
contentType:“应用程序/json”,
成功:回调
});
};
返回{
saveQuestion:\u saveQuestion
};
}();
//问题视图模型
sv.QuestionViewModel=函数(数据){
var self=这个;
如果(!data.QuestionType){
data.QuestionType=“未指定”;
}
this.Tags=ko.observearray([]);
fromJS(数据,{},this);
this.QuestionStatus=ko.computed(函数(){
返回此。已批准?“待定面试问题”:“已批准面试问题”
},这个);
this.TagsText(this.TagsText()| |“无”);
};
//C#
公共课堂访谈问题模型{
公共长Id{get;set;}
公共字符串文本{get;set;}
公共字符串QuestionType{get;set;}
公共长?问题类型ID{get;set;}
公共字符串RequestorName{get;set;}
公共bool IsAdminApproved{get;set;}
公共bool IsActive{get;set;}
公共字符串TagsText{get;set;}
公共列表标记{get;set;}
公众访谈问题模型(){
标签=新列表();
}
}
公共类标签{
[说明(“标签id”)]
公共长Id{get;set;}
[说明(“标签名称”)]
公共字符串名称{get;set;}
公共bool IsActive{get;set;}
公共标签(){
IsActive=假;
}
}
//核准问题视图模型
sv.ApprovedQuestionListViewModel=函数(){
var self=这个;
this.questions=ko.observearray([]);
this.questionCount=ko.computed(函数(){
返回此.questions().length;
},这个);
this.load=函数(){
sv.QuestionService.getApprovedQuestions(函数(数据){
var mapped=ko.utils.arrayMap(数据、函数(项){
返回新sv.QuestionViewModel(项目);
});
自我问题(映射);
});
}.约束(本);
};

QuestionService.saveQuestion函数中的ko.mapping代码工作正常。由于我看不到整个应用程序,所以我无法真正说明是什么原因导致了您的困难。但是,如果我使用QuestionService.saveQuestion函数,它会正确地将函数scope“tags”变量的内容推送到question.tags observable数组中,并且您对ko.mapping.toJSON的调用会正确地生成一个JSON格式的字符串,该字符串可以通过网络传递

以下是我运行的客户端代码,用于练习QuestionService.saveQuestion函数:

<script>
    sv = {};
    sv.QuestionService = function () {
        var _saveQuestion = function (question, callback) {
            var tags = [
            { Id: 1, Name: "food" },
            { Id: 2, Name: "career" },
            { Id: 3, Name: "fax" }  ];
            $.each(tags, function (index, item) {
                question.Tags.push(item);
            });
            console.log(ko.mapping.toJSON(question));

           $.ajax("/Home/saveQuestion", {
                data: ko.mapping.toJSON(question),
                dataType: "json",
                type: "post",
                contentType: "application/json",
                success: sv.Completed
            });
        };
        return {
           saveQuestion: _saveQuestion
        };
    } ();
    sv.Completed = function (data) {     
        alert(data.message);
    };

    var input = { Tags : ko.observableArray([])};
    sv.QuestionService.saveQuestion(input, sv.Completed);
</script>
我在服务器端看到一组C#标记对象,其中包含三个成员:


因此,QuestionService.saveQuestion函数正确地使用ko.mapping.toJSON将ViewModel的部分序列化为JSON字符串。您遇到的问题必须在代码的其他部分。

Hi Abe。通过调用ko.mapping.toJSON,QuestionService.saveQuestion函数似乎正确序列化了数组(请参阅下面的答案)。如果您可以发布客户端javascript中调用函数的部分,那么就有可能找到问题所在。但是实际函数看起来很好。嗨,Joe,ko.mapping.toJSON确实序列化了Tags子属性,但是不知为什么属性Id和Name是空的或null。嗨,Abe。在我发布的示例代码中,Id和NAme属性被填充并正确发送到服务器。我通过屏幕截图更新了这一点。如果您可以发布更多的javascript代码,包括对QuestionService.saveQuestion的调用,我将看看是否可以重现这个问题。但现在我不能。谢谢。一个区别似乎是我在变量输入上使用了ko.mapping.fromJS。
{"Tags":[{"Id":1,"Name":"food"},{"Id":2,"Name":"career"},{"Id":3,"Name":"fax"}]}