Last active
August 29, 2015 14:05
-
-
Save begedin/cc02fb31973fa7368430 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// A knockout computed observable that supports async data. | |
/// To use it, set a function that returns a deferred object, for instance, an AJAX call as the parameter. | |
/// While using AJAX, if server data isn't in proper format, you can use $.ajax().pipe() to map it correctly. | |
/// http://api.jquery.com/deferred.pipe/ | |
/// | |
/// There are two helper observables added to the asyncComputed | |
/// .inProgress returns true if data is not yet loaded (is currently being loaded) | |
/// .loaded is the opposite and returns true if data has been loaded | |
/// </summary> | |
/// <param name="evaluator">deferred (or regular) function</param> | |
/// <param name="owner">what the 'this' of the function will be set to</param> | |
/// <returns type="deferred">null while deferred isn't resolved, result after deferred is resolved.</returns> | |
ko.asyncComputed = function (evaluator, owner) { | |
var result = ko.observable(), currentDeferred; | |
result.inProgress = ko.observable(false); // Track whether we're waiting for a result | |
result.loaded = ko.computed(function () { return !result.inProgress(); }); // Helper to track if data is loaded. | |
ko.computed(function () { | |
// Abort any in-flight evaluation to ensure we only notify with the latest value | |
if (currentDeferred) { currentDeferred.reject(); } | |
var evaluatorResult = evaluator.call(owner); | |
// Cope with both asynchronous and synchronous values | |
if (evaluatorResult && (typeof evaluatorResult.done == "function")) { // Async | |
result.inProgress(true); | |
currentDeferred = $.Deferred().done(function (data) { | |
result.inProgress(false); | |
result(data); | |
}); | |
evaluatorResult.done(currentDeferred.resolve); | |
} else // Sync | |
result(evaluatorResult); | |
}); | |
return result; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment