2012-08-14 76 views
2

我遇到了knockout.js绑定问题,显示可能从ASP.NET Web Api中无法使用的子对象。Knockout.js不显示子对象

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

如何重现该问题

在用户界面上,如果用户选择与音符的客户,再敲结合并正确显示的音符。如果用户选择没有记录的客户,则不显示任何内容(如预期的那样),但是当用户随后选择具有记录的另一个客户时,不显示(意外)。

的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的HTML

<h2>Customers</h2> 
<div class="row-fluid"> 
    <div class="span8"> 
     <!--Customer List using Datatable--> 
     <table id="customerlist" class="display"> 
      <thead> 
       <tr> 
        <th>Company Name</th> 
        <th>Customer Type</th>    
       </tr> 
      </thead> 
      <tbody> 
      </tbody> 
     </table> 
    </div> 
    <div class="span4"> 
     <div class="row-fluid"> 
      <div id="accordion"> 
       <h3><a href="#"><div id="displayname">[displayname]</div></a></h3> 
        <div> 
         <div data-bind="text: party().PartyID"></div> 
         <div data-bind="text: party().StoreID"></div> 
         <!--pre data-bind="text: ko.toJSON($data)"></pre--> 
        </div> 
       <h3><a href="#">People</a></h3> 
        <div> 
        <ul data-bind="foreach: party().People"> 
         <li class="ui-widget" style="list-style-type: none; list-style-position: inside;"> 
          <span data-bind="text: LastName"></span>, <span data-bind="text: FirstName"></span> 
         </li> 
        </ul> 
        </div> 
       <h3><a href="#">Notes</a></h3> 
        <div> 
        <ul data-bind="foreach: party().Notes"> 
         <li class="ui-widget" style="list-style-type: none; list-style-position: inside;"> 
          <span data-bind="text: NoteText"></span> 
         </li> 
         <li class="ui-widget" style="list-style-type: none; list-style-position: inside;"> 
          <span data-bind="text: NoteID"></span> 
         </li> 
        </ul> 
        </div> 
      </div> 
     </div> 
    </div> 
</div> 

例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"}]}} 

例JSON从没有注意Web API。

{"$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"}]}} 

回答

0

终于能弄明白了。每次用户选择数据表行时,我都会调用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); 

然后,当用户在数据表中点击一排只需要调用GetParty在fnRowSelected功能。

viewModel.GetParty(id);