solidstate
Version:
An observable REST client for Javascript with a dramatically simple & fluent API.
62 lines (50 loc) • 2.28 kB
JavaScript
if (typeof define !== 'function') { var define = require('amdefine')(module); }
define([
'knockout',
'underscore',
'./Link',
'../misc'
], function(ko, _, Link, misc) {
'use strict';
var o = ko.observable,
u = ko.utils.unwrapObservable,
c = ko.computed,
w = function(v) { return ko.isObservable(v) ? v : o(v); };
// FilterLink :: { String: Model -> String|Number } -> (Link -> Link)
//
// The same as the input link, but adds filters based on a dictionary
// of input functions. It combines the values from all the models
// into a single filter.
//
var FilterLink = function(filters) {
filters || die('Missing required arg `filters` for FilterLink');
return function(link) {
link || die('Missing required arg `link` for FilterLink');
return new Link({
resolve: function(sourceCollection) {
var target = link.resolve(sourceCollection);
var targetData = c(function() {
var data = {};
_(filters).each(function(fn, key) {
var vals = _.chain(sourceCollection.models())
.values()
.map(u)
.map(fn)
.filter(function(v) { return _(v).isString() || _(v).isNumber(); })
.uniq()
.value()
.sort();
if ( _(vals).isEmpty() ) vals = misc.NOFETCH;
data[key] = vals;
});
// And... danger / hardcoding for tastypie for now (can actually be easily expressed in the client code, but verbose)
data.limit = 0;
return data;
}).extend({throttle: 1});
return target.withFields({ data: targetData });
}
});
};
};
return FilterLink;
});