Skip to content Skip to sidebar Skip to footer

Knockout Is Slow When Unchecking Checkboxes On A Large (1000) Dataset

I am using this code, to check all checkboxes on my view. var checked = self.includeAllInSoundscript(); var contents = self.filterContents(self.getFilters()); for (var i = 0; i &l

Solution 1:

This is what I use for this scenario. Maybe it will help you.

The checked binding can work with an array of selected items, but only supports storing strings in the array. I use a custom binding that supports storing objects in the array (like selectedOptions does):

ko.bindingHandlers.checkedInArray = {
    init: function (element, valueAccessor) {
        ko.utils.registerEventHandler(element, "click", function() {
            var options = ko.utils.unwrapObservable(valueAccessor()),
                array = options.array, // don't unwrap array because we want to update the observable array itself
                value = ko.utils.unwrapObservable(options.value),
                checked = element.checked;
            ko.utils.addOrRemoveItem(array, value, checked);
        });
    },
    update: function (element, valueAccessor) {
        var options = ko.utils.unwrapObservable(valueAccessor()),
            array = ko.utils.unwrapObservable(options.array),
            value = ko.utils.unwrapObservable(options.value);

        element.checked = ko.utils.arrayIndexOf(array, value) >= 0;
    }
};

The binding for each checkbox then looks like this:

<input type="checkbox" data-bind="checkedInArray: { array: $parent.selectedItems, value: $data }" />

The checkbox for selecting all items uses the normal checked binding and is attached to a writable computed observable:

this.allItemsSelected = ko.computed({
    read: function() {
        returnthis.selectedItems().length === this.items().length;
    },
    write: function(value) {
        this.selectedItems(value ? this.items.slice(0) : [] );
    },
    owner: this
});

Example: http://jsfiddle.net/mbest/L3LeD/

Update: Knockout 3.0.0 introduced the checkedValue binding option that makes the above custom binding unnecessary. You can now bind the checkboxes like this:

<input type="checkbox" data-bind="checked: $parent.selectedItems, checkedValue: $data" />

Example: http://jsfiddle.net/mbest/RLLX6/

Solution 2:

What happens to performance if you use jQuery to check/uncheck all the boxes?

$('#tableId').find('input[type=checkbox]').prop('checked', checked);

Alternatively, could you check all the boxes when you display them, rather than doing all of them in one go?

Also, you could try using the knockout.utils methods for filtering the observable arrays, I'd be interested to see if there's any performance difference there.

var filteredArray = ko.utils.arrayFilter(this.items(), function(item) {
        return ko.utils.stringStartsWith(item.name().toLowerCase(), filter);
    });

There is also a method for looping over an array and processing each element:

ko.utils.arrayForEach(this.items(), function(item) {
    var value = parseFloat(item.priceWithTax());
    if (!isNaN(value)) {
        total += value;
    }
});

Again, I have no idea if this will help with performance or not, though I think it's a bit better prettiness-wise!

Post a Comment for "Knockout Is Slow When Unchecking Checkboxes On A Large (1000) Dataset"