问题
angularjs has the angular-filters 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 knockout.js?
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.
回答1:
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 providesfilter
: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 yourfilter
callback.
回答2:
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?
来源:https://stackoverflow.com/questions/32101131/is-there-something-like-angularjs-filters-for-knockout-js