Raju Putchala
Raju Putchala

Reputation: 96

How to apply multiple filters on observable array in knockout

I have an observable array in my self object, self.taskItems, which I've used in knockout foreach binding to display the content of each task.

Based on some task filters I need to change the contents of taskItems, then when clear filters is clicked, I need to show my original content.

To achieve this functionality I've cloned the above observable array into another array self.taskpanelAllItems(self.taskItems());

The issue is that when I'm removing content from taskItems() it is removing content from my cloned array in taskpanelAllItems(), how to prevent this?

What is the best way to work in these situations: cloning the original array and modifying that or is there any other way?

Upvotes: 0

Views: 755

Answers (2)

Michael Best
Michael Best

Reputation: 16688

self.taskpanelAllItems(self.taskItems());

This doesn't clone the array. It merely assigns the same array to another observable. You end up with two observables pointing to the same array.

To clone the array, you need to specifically call a function that does so:

self.taskpanelAllItems(self.taskItems.slice(0));

As @Tomalak suggests, though, using a computed observable is a better approach that encapsulates the relationship between the observable clearly.

Upvotes: 0

Tomalak
Tomalak

Reputation: 338326

Based on some task filters I need to change this taskItems contents, when clear filters is clicked, I need to show my original content.

Don't try to maintain a second (cloned) list of items manually.

Instead you should set a filter observable:

self.filter = ko.observable();

and a computed:

self.visibleTaskItems = ko.computed(function () {
    var filterValue = self.filter();
    return ko.utils.arrayFilter(self.taskItems(), function (taskItem) {
        // some sort of filter condition
        return !filterValue || taskItem.title().indexOf(filterValue) > - 1;
    });
});

Now you can let your view depend on visibleTaskItems:

<ul data-bind="foreach: visibleTaskItems">
  <li data-bind="text: title">
</ul>

Now everytime you change or clear the filter, your view updates accordingly.

Upvotes: 1

Related Questions