I have a function that performs some communication with a server to report the current screen geometry, etc.
function sendScreenLayout() {
logElementLocations(exp.getPageCoordinates());
};
I subscribe this function to some events in my code like this:
viewModel.onLayoutChange.subscribe(sendScreenLayout);
$('#right-splitter > #mainContent').resize(sendScreenLayout);
$(window).resize(sendScreenLayout);
...
setTimeout(sendScreenLayout, 1);
Some of these events may get sent too frequently to be usefully handled by the server, and I would like to throttle the requests to some reasonable rate.
The best I could come up with was something like this:
var triggerSend = ko.observable();
ko.computed(function() {
triggerSend();
logElementLocations(exp.getPageCoordinates());
}).extend({throttle: 200});
function sendScreenLayout() {
triggerSend.valueHasMutated();
}
Is there a more succinct way of capturing this pattern, or is this the way to go?
Deferred – Notifications happen asynchronously, immediately after the current task and generally before any UI redraws. Rate-limited – Notifications happen after the specified period of time (a minimum of 2-10 ms depending on the browser).
KnockoutJS is basically a library written in JavaScript, based on MVVM pattern that helps developers build rich and responsive websites.
An observable is useful in various scenarios where we are displaying or editing multiple values and require repeated sections of the UI to appear and disappear as items are inserted and deleted. The main advantage of KO is that it updates our UI automatically when the view model changes.
If you are using Underscore, you could use debounce
like this:
var sendScreenLayout = _.debounce(function() {
logElementLocations(exp.getPageCoordinates());
}, 200);
...
$(window).resize(sendScreenLayout);
...
Otherwise, it's not really a pattern that Knockout supports directly. The solution you came up seems good enough, although here's an alternative:
var triggerSend = ko.computed({
read: function() {},
write: function(dummy) {
logElementLocations(exp.getPageCoordinates());
}
}).extend({throttle: 200});
function sendScreenLayout() {
triggerSend(true);
}
Assuming your viewModel.onLayoutChange
is an observable, you can simply do:
ko.computed(function() {
viewModel.onLayoutChange(); //implicitly subscribes this callback to changes
logElementLocations(exp.getPageCoordinates());
}).extend({throttle: 200});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With