Question

I'm using jQWidgets UI framework with Knockout.js and datajs library(for supporting OData) for building client side of my app. And OData Endpoint in ASP.NET Web API2 at the server side. I created ViewModel for jqWidgets Grid as in code below:

    var vm = function() {
        this.items = ko.observableArray();
        var self = this;

        //qet data from service 
        OData.read(url,
            function success(data, response) {
                //convert data to observable array
                self.items(data.results);
            },
            function error(err) {
                alert(err.message); 
            });


        this.removeItem = function() {
            // remove item
            var element = "#jqxgrid";
            var cell = $(element).jqxGrid('getselectedcell');
            if (cell != null && cell != "") {
                var selectedrowindex = cell.rowindex;
            };

            var item =$(element).jqxGrid('getrowdata', selectedrowindex);

            OData.request({
                requestUri: url + '(' + item.CompanyID + ')',
                method: "DELETE",
            },
            function success(data, response) {
                alert('DELETE successfull');
            },
            function error(err) {
                alert(err.message); 
            });
        };

As you see I can get and remove items. My problem is how to save ALL changes and send JUST changed items to server. For add/update entities at server side I have to send POST/PUT request with appropriate json object (not collection of objects). So, for example, if I want to update all changed items, i have to do PUT request for each item. Is it any way to detect which items in observableArray was added/changed and send each of those items to server??

Was it helpful?

Solution

knockout does not do this out of the box. What I have done in the past is set an isDirty flag in the object stored in the array (this assumes your object is populated with observables, if not this wont work, and there is no easy way to do it using regular js objects). The is dirty flag watches the observable properties for changes and when on is made it sets the flag to true. Then when saves are being made you just see if the record for isDirty() == true

var entryForm = function(){
var self = this;
self.firstName = ko.observable();
self.lastName = ko.observable();
self.email = ko.observable();
self.dirty = ko.observable(false);
self.dirtyCalculations = ko.computed(function(){
    //read from any observable we want to watch as part of our "dirty" calculation
    self.firstName();
    self.lastName();
    self.email();

    //if any of the above changed, this method will be called, so this model is now "dirty"
    self.dirty(true);
});

//see the next section for an explanation of these lines
self.resetDirtyFlag = function(){self.dirty(false);}
self.resetDirtyFlag();
}

I see in your code above that you plug your return object straight into the array without converting the properties to observable. I would suggest converting the properties and using a similar method above.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top