CraigCav/ko.datasource — pull request #5 by agrath (2013-10-25 04:04:50+00:00)
Title: Update ko.datasource.js to synchronise multiple invokes and extend to add ajax capabilities

*Synchronise multiple invokes*

When generator function is called, it is wrapped in a function which tracks how many times it has been invoked and only sets the observable if it is the last invoke.
A new parameter is passed to the generator function, callback, which you should call with the value.
Backwards compatibility is maintained so if you still set observable (bound to this) everything will still work.
If you use the callback pattern, a new flag, async applies, as such:

Original Syntax:
self.data = ko.observable().extend({ datasource: self.getData });
New Syntax:
self.data = ko.observable().extend({ datasource: { generator: self.getData, async: true } });

If async is true, then only the last result from calling generator will be applied.
Therefore, you can still do whatever you want inside generator, such as just returning a local calculation or invoking a remote service and returning the result.
If async is false, then every result from calling generator will be applied.
Note: you must be using callback(value) inside your generator function if you wish to use async mode.

*extend to add ajax capabilities*

If you pass generator as a javascript object with options:
url; the remote url
method; the ajax method (get|post)
params; parameters to pass to remote handler (unwrapped and subscribed)

Then datasource will handle the ajax request internally. If async is true, multiple invokes will abort the previous xhr before issuing a new one.

self.refresh = function(){ self.trigger(Math.random()) }
self.trigger = ko.observable(Math.random());
self.data = ko.observable().extend({ datasource: { generator: { url: '/RemoteData.ashx', method: 'post', params: { q: 'test', trigger: self.trigger } }, async: true } });

Ajax functionality borrows parseJSON from jQuery and a modified version of tinyxhr from https://gist.github.com/shimondoodkin/4706967