Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Knockout - display progress image during rendering

Tags:

knockout.js

I have a page using Knockout to display a filtered list. The view model has an array of objects, and a ko.computed that uses ko.utils.arrayFilter to filter the array.

Occasionally the filtering can get quite complex and take a while, so I'd like to display a progress image to show that something is going on and the world hasn't come to an end.

What's the best way to do this? I've tried using an observable on the view model that gets set at the start and end of the filtering method, but that doesn't seem to work.

Or are there events you can use before and after Knockout starts updating?

I'm new to Knockout so there may be something obvious that I've missed!

JS Fiddle here: http://jsfiddle.net/jsayce/pSzSw/, showing my attempt at setting an observable on the filtering method.

like image 582
Jonathan Sayce Avatar asked Apr 29 '26 22:04

Jonathan Sayce


1 Answers

To make this work you have to run long operation in another thread. You can do this using setTimeout function or use any fancy third-party library for this. Here is quick solution:

var cheeseViewModel = function() {
    var self = this;

    self.englishOnly = ko.observable(false);
    self.filtering = ko.observable(false);

    self.cheeses = ko.observableArray([]);
    self.cheeses.push(new cheese('Camembert', false));
    self.cheeses.push(new cheese('Stilton', true));
    self.cheeses.push(new cheese('Brie', false));
    self.cheeses.push(new cheese('Appenzeller', false));
    self.cheeses.push(new cheese('Wensleydale', true));

    self.selectedCheeses = ko.observableArray(self.cheeses());

    self.englishOnly.subscribe(function() {
        self.filtering(true);

        setTimeout(function() {
            var filteredCheeses = ko.utils.arrayFilter(self.cheeses(), function(cheese) {
                createSlowness();
                return cheese.madeInEngland || !self.englishOnly();
            });

            self.selectedCheeses(filteredCheeses);
            self.filtering(false);
        }, 20);
    });

Here is working fiddle: http://jsfiddle.net/pSzSw/6/

like image 165
Artem Vyshniakov Avatar answered May 05 '26 10:05

Artem Vyshniakov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!