Knockout.js不显示子对象

Knockout.js不显示子对象,knockout.js,asp.net-web-api,Knockout.js,Asp.net Web Api,我在获取knockout.js绑定以显示可能从ASP.NET Web Api为空的子对象时遇到问题 我基本上是在尝试创建一个可搜索的客户列表(使用Jquery Datatable插件),用户将选择一个客户记录来检索客户的全部详细信息(姓名、订单历史记录、客户注释等)。此客户详细信息将显示在datatable的侧面,某些字段将可编辑。在我的数据模型中,客户可以有零个、一个或多个注释,而这正是我遇到问题的对象 如何重现问题 在UI上,如果用户选择了一个带有注释的客户,那么将绑定并正确显示注释。如果用

我在获取knockout.js绑定以显示可能从ASP.NET Web Api为空的子对象时遇到问题

我基本上是在尝试创建一个可搜索的客户列表(使用Jquery Datatable插件),用户将选择一个客户记录来检索客户的全部详细信息(姓名、订单历史记录、客户注释等)。此客户详细信息将显示在datatable的侧面,某些字段将可编辑。在我的数据模型中,客户可以有零个、一个或多个注释,而这正是我遇到问题的对象

如何重现问题

在UI上,如果用户选择了一个带有注释的客户,那么将绑定并正确显示注释。如果用户选择了一个带注释的客户,则不会显示任何内容(如预期),但当用户选择另一个带注释的客户时,则不会显示任何内容(意外)

javascript:

$(document).ready(function () {

    //Party Model.
    var PartyModel = function (id) {
        var self = this;
        self.loaded = ko.observable(false);
        self.party = ko.observableArray([]);

        $.getJSON('api/party/GetParty?id=' + id, self.party).done(function () {
            self.loaded(true);
        });
    };

    //Customer List Datatable which is displayed on the left.
    custlisttable = $('#customerlist').dataTable({
        //"bServerSide": true,
        "bProcessing": true,
        "bPaginate": false,
        "sAjaxSource": "api/PartyNameView/GetvPartyNamebyStoreID?storeid=1600", //"api/PartyNameView/GetvPartyName?id=2",
        "sAjaxDataProp": "",
        "sDom": 'R<"H"lfr>t<"F"iTp>',
        "bJQueryUI": true,
        "aoColumns": [
                { "mDataProp": "DisplayName" },
                { "mDataProp": "PartyCategoryDesc"}],
        "oTableTools": {
            "sRowSelect": "single",
            "aButtons": [],
            "fnRowSelected": function (node) {
                aData = custlisttable.fnGetData(node); 
                $('#displayname').html(aData.DisplayName);
                id = aData.PartyID                      
                //get new party model using the PartyID (customerid).
                ko.applyBindings(new PartyModel(id));
                $("#accordion").show(750);
            }
        }
    });

    //Define the Contact Detail Accordian Section, but hide it until a record is selected.
    $("#accordion").accordion();
    $("#accordion").hide();
    $('.accordion .head').click(function () {
        $(this).next().toggle();
        return false;
    }).next().hide();
}); 
不带注释的Web API JSON示例。

{"$id":"1","PartyID":1,"StoreID":"1600 ","ApprovedforAR":false,"PartyCategoryID":1,"PartyTypeID":1,"OrganizationID":1,"InvoiceHeaders":[],"Notes":[{"$id":"2","NoteID":2,"NoteText":"Test Note 1","PartyID":1,"Party":{"$ref":"1"},"PeopleNotes":[],"EntityKey":{"$id":"3","EntitySetName":"Notes","EntityContainerName":"appCateringFulfillmentEntities","EntityKeyValues":[{"Key":"NoteID","Type":"System.Int32","Value":"2"}]}},{"$id":"4","NoteID":3,"NoteText":"Deliveries only after 5","PartyID":1,"Party":{"$ref":"1"},"PeopleNotes":[],"EntityKey":{"$id":"5","EntitySetName":"Notes","EntityContainerName":"appCateringFulfillmentEntities","EntityKeyValues":[{"Key":"NoteID","Type":"System.Int32","Value":"3"}]}}],"PartyCategory":{"$id":"6","PartyCategoryID":1,"PartyCategoryDesc":"Category 1","Parties":[{"$ref":"1"}],"EntityKey":{"$id":"7","EntitySetName":"PartyCategories","EntityContainerName":"appCateringFulfillmentEntities","EntityKeyValues":[{"Key":"PartyCategoryID","Type":"System.Int32","Value":"1"}]}},"PartyType":{"$id":"8","PartyTypeID":1,"PartyTypeDesc":"Party Type 1","Parties":[{"$ref":"1"},{"$id":"9","PartyID":2,"StoreID":"1600 ","ApprovedforAR":false,"PartyCategoryID":2,"PartyTypeID":1,"InvoiceHeaders":[],"Notes":[],"PartyCategory":{"$id":"10","PartyCategoryID":2,"PartyCategoryDesc":"Category 2","Parties":[{"$ref":"9"}],"EntityKey":{"$id":"11","EntitySetName":"PartyCategories","EntityContainerName":"appCateringFulfillmentEntities","EntityKeyValues":[{"Key":"PartyCategoryID","Type":"System.Int32","Value":"2"}]}},"PartyType":{"$ref":"8"},"People":[{"$id":"12","PersonID":2,"FirstName":"Tom","LastName":"Harber","Title":"Accounting","PartyID":2,"Notes":[],"Party":{"$ref":"9"},"EntityKey":{"$id":"13","EntitySetName":"People","EntityContainerName":"appCateringFulfillmentEntities","EntityKeyValues":[{"Key":"PersonID","Type":"System.Int32","Value":"2"}]}}],"PostalAddresses":[],"ChannelAddresses":[],"EntityKey":{"$id":"14","EntitySetName":"Parties","EntityContainerName":"appCateringFulfillmentEntities","EntityKeyValues":[{"Key":"PartyID","Type":"System.Int32","Value":"2"}]}}],"EntityKey":{"$id":"15","EntitySetName":"PartyTypes","EntityContainerName":"appCateringFulfillmentEntities","EntityKeyValues":[{"Key":"PartyTypeID","Type":"System.Int32","Value":"1"}]}},"People":[{"$id":"16","PersonID":3,"FirstName":"Jared","LastName":"Kirkwood","Title":"Owner","PartyID":1,"Notes":[],"Party":{"$ref":"1"},"EntityKey":{"$id":"17","EntitySetName":"People","EntityContainerName":"appCateringFulfillmentEntities","EntityKeyValues":[{"Key":"PersonID","Type":"System.Int32","Value":"3"}]}}],"PostalAddresses":[],"Organization":{"$id":"18","OrganizationID":1,"OrganizationName":"Tony's Pizza Company","TaxExempt":false,"Parties":[{"$ref":"1"}],"EntityKey":{"$id":"19","EntitySetName":"Organizations","EntityContainerName":"appCateringFulfillmentEntities","EntityKeyValues":[{"Key":"OrganizationID","Type":"System.Int32","Value":"1"}]}},"ChannelAddresses":[],"EntityKey":{"$id":"20","EntitySetName":"Parties","EntityContainerName":"appCateringFulfillmentEntities","EntityKeyValues":[{"Key":"PartyID","Type":"System.Int32","Value":"1"}]}}
{"$id":"1","PartyID":2,"StoreID":"1600 ","ApprovedforAR":false,"PartyCategoryID":2,"PartyTypeID":1,"InvoiceHeaders":[],"Notes":[],"PartyCategory":{"$id":"2","PartyCategoryID":2,"PartyCategoryDesc":"Category 2","Parties":[{"$ref":"1"}],"EntityKey":{"$id":"3","EntitySetName":"PartyCategories","EntityContainerName":"appCateringFulfillmentEntities","EntityKeyValues":[{"Key":"PartyCategoryID","Type":"System.Int32","Value":"2"}]}},"PartyType":{"$id":"4","PartyTypeID":1,"PartyTypeDesc":"Party Type 1","Parties":[{"$ref":"1"},{"$id":"5","PartyID":1,"StoreID":"1600 ","ApprovedforAR":false,"PartyCategoryID":1,"PartyTypeID":1,"OrganizationID":1,"InvoiceHeaders":[],"Notes":[{"$id":"6","NoteID":2,"NoteText":"Hello Party World","PartyID":1,"Party":{"$ref":"5"},"PeopleNotes":[],"EntityKey":{"$id":"7","EntitySetName":"Notes","EntityContainerName":"appCateringFulfillmentEntities","EntityKeyValues":[{"Key":"NoteID","Type":"System.Int32","Value":"2"}]}},{"$id":"8","NoteID":3,"NoteText":"It's Tomato Fest","PartyID":1,"Party":{"$ref":"5"},"PeopleNotes":[],"EntityKey":{"$id":"9","EntitySetName":"Notes","EntityContainerName":"appCateringFulfillmentEntities","EntityKeyValues":[{"Key":"NoteID","Type":"System.Int32","Value":"3"}]}}],"PartyCategory":{"$id":"10","PartyCategoryID":1,"PartyCategoryDesc":"Category 1","Parties":[{"$ref":"5"}],"EntityKey":{"$id":"11","EntitySetName":"PartyCategories","EntityContainerName":"appCateringFulfillmentEntities","EntityKeyValues":[{"Key":"PartyCategoryID","Type":"System.Int32","Value":"1"}]}},"PartyType":{"$ref":"4"},"People":[{"$id":"12","PersonID":3,"FirstName":"Jared","LastName":"Kirkwood","Title":"Owner","PartyID":1,"Notes":[],"Party":{"$ref":"5"},"EntityKey":{"$id":"13","EntitySetName":"People","EntityContainerName":"appCateringFulfillmentEntities","EntityKeyValues":[{"Key":"PersonID","Type":"System.Int32","Value":"3"}]}}],"PostalAddresses":[],"Organization":{"$id":"14","OrganizationID":1,"OrganizationName":"Tony Tomato's Pizza Company","TaxExempt":false,"Parties":[{"$ref":"5"}],"EntityKey":{"$id":"15","EntitySetName":"Organizations","EntityContainerName":"appCateringFulfillmentEntities","EntityKeyValues":[{"Key":"OrganizationID","Type":"System.Int32","Value":"1"}]}},"ChannelAddresses":[],"EntityKey":{"$id":"16","EntitySetName":"Parties","EntityContainerName":"appCateringFulfillmentEntities","EntityKeyValues":[{"Key":"PartyID","Type":"System.Int32","Value":"1"}]}}],"EntityKey":{"$id":"17","EntitySetName":"PartyTypes","EntityContainerName":"appCateringFulfillmentEntities","EntityKeyValues":[{"Key":"PartyTypeID","Type":"System.Int32","Value":"1"}]}},"People":[{"$id":"18","PersonID":2,"FirstName":"Allen","LastName":"Harber","Title":"Helpdesk","PartyID":2,"Notes":[],"Party":{"$ref":"1"},"EntityKey":{"$id":"19","EntitySetName":"People","EntityContainerName":"appCateringFulfillmentEntities","EntityKeyValues":[{"Key":"PersonID","Type":"System.Int32","Value":"2"}]}}],"PostalAddresses":[],"ChannelAddresses":[],"EntityKey":{"$id":"20","EntitySetName":"Parties","EntityContainerName":"appCateringFulfillmentEntities","EntityKeyValues":[{"Key":"PartyID","Type":"System.Int32","Value":"2"}]}}

最后,我终于找到了答案。每次用户选择datatable行时,我都调用applyBindings。根据我发现的一些信息,这是一种不好的做法

新视图模型

viewModel = {
    Party: ko.observableArray([]),
    GetParty: function (id) {
        //Reset Party
        this.Party([]);
        //Retrieve the new data from the server.
        $.ajax({ url: "api/party/GetParty?id=" + id,
            accepts: "application/json",
            cache: false,
            statusCode: {
                200: function (data) {
                    viewModel.Party(data);
                }
                //TODO Handle other status codes
            }
        });
    }
};
ko.applyBindings(viewModel);
然后,当用户单击datatable中的一行时,只需调用fnRowSelected函数中的GetParty

viewModel.GetParty(id);

最后,我终于找到了答案。每次用户选择datatable行时,我都调用applyBindings。根据我发现的一些信息,这是一种不好的做法

新视图模型

viewModel = {
    Party: ko.observableArray([]),
    GetParty: function (id) {
        //Reset Party
        this.Party([]);
        //Retrieve the new data from the server.
        $.ajax({ url: "api/party/GetParty?id=" + id,
            accepts: "application/json",
            cache: false,
            statusCode: {
                200: function (data) {
                    viewModel.Party(data);
                }
                //TODO Handle other status codes
            }
        });
    }
};
ko.applyBindings(viewModel);
然后,当用户单击datatable中的一行时,只需调用fnRowSelected函数中的GetParty

viewModel.GetParty(id);