Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rate limiting all observables by default

Is there a way in knockout.js to rate limit all observables by default?

I'd like to not have to extend all my observables one by one.

like image 889
Koen Peters Avatar asked May 13 '15 15:05

Koen Peters


3 Answers

You can create a function to use instead of ko.observable. I do this just to save typing, myself:var KOB = ko.observable;

For your case, it would be (something like):

var KOB = function (value) {
    return ko.observable(value).extend({rateLimit:500});
};
like image 84
Roy J Avatar answered Nov 07 '22 20:11

Roy J


Monkey see, monkey do: monkey patch!

But first, let me say that AFAIK there is no way to do what you want with a Knockout feature; there is no global setting (anything like ko.globalSettings["defaultRateLimit"]) to set default rate limits for all future observables.

Nonetheless, here's a way to monkey patch Knockout in a straightforward way to do exactly as you ask. However, I'd consider this a rather late/last resort: with monkey patching you never know how it'll affect future releases of a framework. Also, this will irrevocably change ko.observable so that it does what you ask, no exceptions.

(function() {
  var originalObservableFn = ko.observable;
  ko.observable = function(x) {
    return originalObservableFn(x).extend({rateLimit: 1500});
  }
})();

var vm = {
  myValue: ko.observable("initial value")
};

ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

Change value here: <input data-bind="textInput: myValue" autofocus /><br />
Read only version: <span data-bind="text: myValue"></span>

For a more scoped solution I'd recommend @RoyJ's solution where you create a new shorthand function to do what you want. It allows you quite a bit more control, which is great because I can't quite imagine any practical production scenario where you want all observables rateLimited, not in the least because it makes unit testing them quite a bit harder as updates become asynchronous.

A final option of course would be to fork Knockout itself, which is easy as it's source is available on GitHub.

like image 44
Jeroen Avatar answered Nov 07 '22 20:11

Jeroen


You could create a function on ko.observable that would add some syntactical sugar to your code. http://knockoutjs.com/documentation/fn.html

so instead of writing ko.observable(value).extend({rateLimit: 500})

it could be possible to write ko.observable(value).limit(500)

I havent tested this yet but would be worth exploring this or possibly a custom binding data-bind="rateLimitValue: fullName"

like image 1
BillPull Avatar answered Nov 07 '22 22:11

BillPull