Search code examples
javascriptknockout.jsknockout-mapping-plugin

Adding an Observable Property to a mapped Observable Array using Knockout JS Mapping Options


I am binding a table in a view using a Knockout observable array (self.data) which is populated by an AJAX call and the Knockout Mapping plugin. The aim is to have the ViewModel as a reusable component.

I need to add in a column to select table rows. I want to do this by adding a boolean isSelected observable property to each item in the self.data observable array using mapping options. This observable property is then used by the self.selectClicked function to push or pop items to the self.selectedItems observable array.

Problem is, I'm not quite sure how to add the isSelected property to each array item.

Here is the code at the moment:

//// NOTE: ko.applyBindings and the AJAX call currently happen outside of this code.

function ViewModel() {

var self = this;

var mapping = {
    // Boolean observable property for each array item added here?
};

self.data = ko.observableArray([]);
self.selectedItems = ko.observableArray([]);

self.selectClicked = function (data, event) {

    if (event.currentTarget.checked) {
        self.selectedItems.push(data);                       
    }
    else {
        self.selectedItems.pop(data);
    }

    return true;
};

// AJAX Data is pushed to the self.data observable array through this function
self.addData = function (_data) {

    ko.mapping.fromJS(_data, mapping, self.data);

};
}

Solution

  • You could manually create the data objects and add isSelected using create:

    var mapping = 
    {
        create: function(_data) {
            return new Data(_data.data);
        }
    };
    
    self.addData = function (_data) {
        ko.mapping.fromJS(_data, mapping, self.data);
    };
    
    var Data = function (data) {
        var self = this;
    
        ko.mapping.fromJS(data, {}, self);
    
        self.isSelected = ko.observable(false);
    };
    

    JsFiddle

    This is documented in the Knockout mapping plugin documentation.