Update ko.datasource.js to synchronise multiple invokes and extend to add ajax capabilities #5
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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