0

has the concept built-in, so it's very easy to reduce a dataset to those elements that match for example a user-input.

Is there something similar available for ?

Of course I could implement it on my own, using plain old Javascript, but I'm not a performance expert so my own solution would probably be horribly slow.

Anish Patel
  • 4,332
  • 1
  • 30
  • 45
connexo
  • 53,704
  • 14
  • 91
  • 128
  • 1
    There is no such thing built in to the core KO library. So you need to implement your "filter" logic in regular js functions or with using ko.computeds. However there is a plugin called: [Knockout.Punches](http://mbest.github.io/knockout.punches/) which provides an angular like filter capatilibity: http://mbest.github.io/knockout.punches/#built-in-filters – nemesv Aug 19 '15 at 17:54
  • 1
    I think the [knockout-projections](https://github.com/stevesanderson/knockout-projections) plugin is what you are looking for. It allows you to create observable arrays that are created from `map` and `filter` functions applied to another observable array. – Anish Patel Aug 20 '15 at 09:31
  • Does this answer your question? [What are the nuances of scope prototypal / prototypical inheritance in AngularJS?](https://stackoverflow.com/questions/14049480/what-are-the-nuances-of-scope-prototypal-prototypical-inheritance-in-angularjs) – Protect children of Donbas2014 Apr 09 '21 at 13:09

2 Answers2

3

Yes, Steve Sanderson has created the knockout-projections plugin for knockout.

This is similar to angular-filters where you can apply a map or filter to a source collection to produce another collection for you to bind to the UI.

This example from the projects github readme demonstrates usage and explains how the map and filter callbacks are executed efficiently:

Mapping

More info to follow. For now, here's a simple example:

var sourceItems = ko.observableArray([1, 2, 3, 4, 5]);

There's a plain observable array. Now let's say we want to keep track of the squares of these values:

var squares = sourceItems.map(function(x) { return x*x; });

Now squares is an observable array containing [1, 4, 9, 16, 25]. Let's modify the source data:

sourceItems.push(6);
// 'squares' has automatically updated and now contains [1, 4, 9, 16, 25, 36]

This works with any transformation of the source data, e.g.:

sourceItems.reverse();
// 'squares' now contains [36, 25, 16, 9, 4, 1]

The key point of this library is that these transformations are done efficiently. Specifically, your callback function that performs the mapping is only called when strictly necessary (usually, that's only for newly-added items). When you add new items to the source data, we don't need to re-map the existing ones. When you reorder the source data, the output order is correspondingly changed without remapping anything.

This efficiency might not matter much if you're just squaring numbers, but when you are mapping complex nested graphs of custom objects, it can be important to perform each mapping update with the minumum of work.

Filtering

As well as map, this plugin also provides filter:

var evenSquares = squares.filter(function(x) { return x % 2 === 0; });
// evenSquares is now an observable containing [36, 16, 4]

sourceItems.push(9);
// This has no effect on evenSquares, because 9*9=81 is odd

sourceItems.push(10);
// evenSquares now contains [36, 16, 4, 100]

Again, your filter callbacks are only called when strictly necessary. Re-ordering or deleting source items don't require any refiltering - the output is simply updated to match. Only newly-added source items must be subjected to your filter callback.

Anish Patel
  • 4,332
  • 1
  • 30
  • 45
1

I think you are looking for functions like: ko.utils.arrayMap ko.utils.arrayForEach ko.utils.arrayFilter ko.utils.arrayFirst

You can find these and much more things at http://www.knockmeout.net/2011/04/utility-functions-in-knockoutjs.html

Does it help you?

Fabio
  • 11,892
  • 1
  • 25
  • 41