psobhan
psobhan

Reputation: 645

Duplicate records are displayed while trying to bind different data to the same div using knockout js

I have a div which displays 10 records a time.When user clicks on next link, the next 10 records will be loaded from server. But after binding, the newly added records are shown multiple times. Kindly help me to know where I am going wrong.

     function displayLastMonthVolume() {            

                $.ajax({
                    type: "POST",
                    url: "DashBoard.aspx/GetLastMonthVolume",
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    success: function (response) {                   
                        if (response != undefined && response != '') {    
                            var data = JSON.parse(response.d);
                            var totalAmt = 0;
                            for (var p = 0; p < data.length; p++) {
                                totalAmt += data[p].Amount;
                            }
                            data.TotalAmt = totalAmt;
ko.cleanNode(document.getElementById('lastmonth_Trans'));    
                            ko.applyBindingsToDescendants(data, document.getElementById('lastmonth_Trans'));    
                        }                        
                    },
                    failure: function (response) {
                        alert(response.d);
                    }
                });    
                return true;
            }

UI :

     <div class="lastmonthdialogpopup" title="Transaction made over the last days">
<table id="lastmonth_Trans" width="100%" cellspacing="0" cellpadding="0" border="0" class="device_tbl" >
  <thead><tr><th valign="middle" align="center">Date</th>
  <th valign="middle" align="left">Merchant Name</th>
  <th valign="middle" align="center"> Amount  </th>
  <th valign="middle" align="left"> Pty_ID </th> </tr></thead>
  <tbody data-bind="foreach: $root">
  <tr><td valign="middle" align="left" data-bind="text: Date"> </td>
   <td valign="middle" align="left" data-bind="text: Name"> </td>
  <td valign="middle" align="right" data-bind="text: Amount.toFixed(2)">
   </td>
  <td valign="middle" align="left" data-bind="text: PtyId"> </td>
  <td valign="middle" align="left" data-bind="text: ID"> </td> </tr>
  </tbody><tfoot><tr><td><b>Total</b></td> <td></td>
  <td valign="middle" align="right" data-bind="text: TotalAmt.toFixed(2)">/td>
 <td></td> </tr> </tfoot></table>
 <a id="expandLink" onclick="displayLastMonthVolume()" style="cursor: pointer; color: #ff8c00;">Next</a> </div>

Upvotes: 1

Views: 635

Answers (1)

Luis
Luis

Reputation: 6001

All you need is to bind once and then replace the new data in the observable array, the 2 way data-binding will replace all the rendered items in the foreach binding with the new ones.

Here is a sample that exemplifies this for you:

var viewModel = {
    // Data
    entries: ko.observableArray(),
    numberOfRecords: ko.observable(),
    dataTimeOfLastCall: ko.observable(),
    retrieveLogs: function() {
        $.ajax({
            type: 'POST',
            url: '/echo/json/',
            data: {
                json: ko.toJSON([
                    { Id: 1, Message: 'message one', Machine: 'machine one', UserId: 'user 1', EntryDate: new Date() },
                    { Id: 2, Message: 'message two', Machine: 'machine two', UserId: 'user 2', EntryDate: new Date() },
                ]),
                delay: 1
            },
            context: this,
            success: function(data) {
                this.entries($.map(data, function(item) {
                    return new logEntry(item);
                }));
            },
            dataType: 'json'
        });
    }
};

function logEntry(item) {
    this.Id = ko.observable(item.Id);
    this.Message = ko.observable(item.Message);
    this.Machine = ko.observable(item.Machine);
    this.UserName = ko.observable(item.UserId);
    this.EntryDate = ko.
    observable(item.EntryDate);

    return this;
}

ko.applyBindings(viewModel);

Notice that every time you click the button the records in the foreach are replaced (check the date changing)

http://jsfiddle.net/luisvsilva/GF3kh/161/

Upvotes: 1

Related Questions