SantyEssac
SantyEssac

Reputation: 809

Refreshing ViewModel after deleting data in Knockout.js

I am using Knockout for binding data of a form to the table,now what i ma facing is that when i am deleting the data from the table it goes to server side and delete the data as well but that data remains there unless we refresh the page which not pratical.So what i tried that i am calling the index method on server side which gives me the list of the datas after refreshing the database but when i am doing this.that refreshed datas are appended to the data that remain on the view.i mean it shows the remaing datas and refreshed data both but pratically it shows only the refreshed datas. My code:

<table id="table2" style="border: double">
    <thead>
        <tr>
            <td>Ticket ID</td>
            <td>Ticket Type</td>
            <td>No of Tickets</td>
            <td>Ticket Price</td>
            <td>Start Date</td>
            <td>End Date</td>
            <td>Action</td>
        </tr>
    </thead>
    <!--Iterate through an observableArray using foreach-->
    <tbody id="ticketid" data-bind="foreach:TicketDatas">
        <tr style="border: solid" data-bind="click: $root.getselectedTicket" id="updtr">
            <td data-bind="text:TicketId">@*<span data-bind="text:No_Of_Ticket"></span>*@</td>
            <td data-bind="text:SelectedTicketType">@*<span data-bind="text:No_Of_Ticket"></span>*@</td>
            <td data-bind="text:No_Of_Ticket">@*<span data-bind="text:No_Of_Ticket"></span>*@</td>
            <td data-bind="text:Ticket_Price">@*<span data-bind="text:Ticket_Price"></span>*@</td>
            <td data-bind="text:Start_Date">@*<span data-bind="text:Start_Date"></span>*@</td>
            <td data-bind="text:End_Date">@*<span data-bind="text:End_Date"></span>*@</td>
            <td><button id="deletelink">Delete</button></td>
        </tr>
    </tbody>
</table>

<script type="text/javascript">
$("#deletelink").live('click', function () {
    if (confirm('Are you sure to Delete this ticket ??')) {
        var deleteLink = $(this);
        var tableRow = deleteLink.closest('tr');
        var firstCell = tableRow.find('td:first-child');
        var tickid = firstCell.text();
        //var tickid = $("#table2 tbody tr td:eq(0)").html();
        $.ajax({
            type: "POST",
            data: { id: tickid },
            url: "Ticket/DeleteTicket",
            //data: "{id:" + ko.toJSON(id) + "}",
            success: function (data) {
                self.TicketDatas.remove(data);
                alert("Record Deleted Successfully");
                //ko.mapping.fromJS(self.TicketDatas, data)
                //GetTickets();//Refresh the Table
            },
            error: function (error) {
                alert(error.status + "<--and--> " + error.statusText);
            }
        });
        // alert("Clicked" + employee.EmpNo)
    }
});

function GetTickets() {
    //Ajax Call Get All Employee Records
    $.ajax({
        type: "GET",
        cache: false,
        url: "Ticket/GetAllTickets",
        contentType: "application/json; charset=utf-8",
        data: {},
        dataType: "json",
        success: function (data) {
            for (var i = 0; i < data.length; i++) {
                self.TicketDatas.push(data[i]);
            }
        },
        error: function (error) {
            alert(error.status + "<--and--> " + error.statusText);
        }
    });
    //Ends Here
}
</script>

Upvotes: 1

Views: 2315

Answers (2)

Zholen
Zholen

Reputation: 1790

Why bother trying to remove a single ticket from your array when shortly after you ask for all tickets? Also I imagine you don't actually want to use a 'push' if GetTickets really is returning all tickets.

<script type="text/javascript">
$("#deletelink").live('click', function () {
    if (confirm('Are you sure to Delete this ticket ??')) {
        var deleteLink = $(this);
        var tableRow = deleteLink.closest('tr');
        var firstCell = tableRow.find('td:first-child');
        var tickid = firstCell.text();

        **DeleteTicket(tickid);**
    }
});

function DeleteTicket(tickid) {
    $.ajax({
        type: "POST",
        data: { id: tickid },
        url: "Ticket/DeleteTicket",
        success: function (data) {
            alert("Record Deleted Successfully");
            **GetTickets()**
        },
        error: function (error) {
            alert(error.status + "<--and--> " + error.statusText);
        }
    });
}

function GetTickets() {
    //Ajax Call Get All Employee Records
    $.ajax({
        type: "GET",
        cache: false,
        url: "Ticket/GetAllTickets",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (data) {
            **self.TicketDatas(data);**
        },
        error: function (error) {
            alert(error.status + "<--and--> " + error.statusText);
        }
    });
    //Ends Here
}
</script>

Upvotes: 0

Joseph Gabriel
Joseph Gabriel

Reputation: 8510

In your ajax call, I notice you have a success handler like this:

success: function (data) {
    self.TicketDatas.remove(data);
    alert("Record Deleted Successfully");
    //ko.mapping.fromJS(self.TicketDatas, data)
    //GetTickets();//Refresh the Table
},

I can see where you're trying to remove the deleted item by calling self.TicketDatas.remove(data);. However, this isn't likely to remove anything from your client-side array of TicketDatas, because you're using the data from the response of the ajax call, and trying to remove that literal object from the array. That actual object isn't in the array, because it was just created from the ajax response.

When removing an object from an array, you either need to reference it by index, or by the an object reference which points to the same memory address as an object in the array.

Try something like this instead:

success: function (data) {
    self.TicketDatas.remove(ko.dataFor(deleteLink));
    ...
},

http://knockoutjs.com/documentation/unobtrusive-event-handling.html

Upvotes: 1

Related Questions