Search code examples
jsondata-bindingknockout.jsdata-objects

Adding additional data to object in Knockout.js


So I've been learning Knockout.js and am really digging it. I'm using it to add some SQL interaction to a guest list on an events website I'm working on. I'm using destroy to mark entries for deletion and handling that by using 'isset' in PHP to mark them as deleted in the DB.

I want to add some sort of functionality to do the same thing when records are updated. It seems unnecissary to update every single record (even know we're only talking 300 updates at the max) when they haven't actually be changed when I send the JSON back to the server. If anyone with more experience working with Knockout can help me out, it would be much appreciated.

Here's my javascript. The markup and data binding is fairly basic so I wont include it.

function Guest(data){
    this.id = ko.observable(data.id);
    this.name = ko.observable(data.name);
    this.email = ko.observable(data.email);
    this.guests = ko.observable(data.guests);
    this.code = ko.observable(data.code);
}

function guestListViewModel(){
    //Data
    var self = this;
    self.guests = ko.observableArray([]);
    self.guestsNumber = 0;

    $.getJSON('/php/guests_json.php', function(json) {
        var mappedGuests = $.map(json, function(item) { return new Guest(item) });
        self.guests(mappedGuests);
        self.guestsNumber = (self.guests().length);
        $('.dlt_btn').button();

    });

    self.removeGuest = function(guest) { 
        self.guests.destroy(guest);
    };

    self.save = function() {
        var data = 'json=' + ko.toJSON({guests: self.guests });
        $.ajax("/php/save_guests.php", {
            data: data,
            type: "post",
            success: function(result) {$('#server').html(result)}
        })
    }

    self.totalGuests = ko.computed(function() {
        var total = 0;
        ko.utils.arrayForEach(self.guests(), function(guest) {
            var value = guest.id;
            console.log(value);
            if (!isNaN(value)) {
                total += value;
            }
        });
        return total;        
    });

}

ko.applyBindings(new guestListViewModel);

Edit

Also, does anyone have any idea why when I'm trying to go through the observable array and pull out the guests value I get a function instead in the console?


Solution

  • Wrap your guest objects with a computed that determines if they're dirty (i.e. edited). Here's a full guide on how to do it:

    http://www.knockmeout.net/2011/05/creating-smart-dirty-flag-in-knockoutjs.html

    Then, you can just submit the ones for whom _isDirty() is true.