KO Lazy Load

by Jason Butz

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-alpha1/jquery.min.js"></script>
<script src=" https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-debug.js"></script>
<p data-bind="text: data1"></p>
<p data-bind="text: data2"></p>

JavaScript

$(document).ready(function(){
/**
 * defferedLoadObservable
 *  Allows a value or a series of values to be loaded only when needed by KO
 * 
 *  Heavily inspired by http://www.knockmeout.net/2011/06/lazy-loading-observable-in-knockoutjs.html
 * 
 *  Created by Jason Butz <[email protected]>
 * 
 * Arguments:
 *  target       - Object that should be passed to the callback for the scope. Usually `self`
 *  options      - Object containing settings values. Values are provided below
 * 
 * Options:
 *  defferedLoadCallback (REQUIRED) - Function that performs the deffered load and sets the returned value
 *                                    function should be shared amongst values that are all loaded with the
 *                                    same request 
 *  defaultValue (OPTIONAL)         - Default value for the observable. Sensible defaults are critical here
 *  dataLoadedObservable (OPTIONAL) - Observable object used as a flag to know if details have been or are being
 *                                    loaded. If no value is provided _hasDetails is created and used. This should
 *                                    be shared amongst values that are all loaded with the same request
 * 
 * Example:
 *  self.loadedData = ko.observable(false);
 *  self.doDataLoad = function() {...};
 *  self.data1 = ko.defferedLoadObservable(self,{
 *      defferedLoadCallback: self.doDataLoad,
 *      defaultValue: "DEFAULT1",
 *      dataLoadedObservable: self.loadedData
 *  });
 *  self.data2 = ko.defferedLoadObservable(self,{
 *      defferedLoadCallback: self.doDataLoad,
 *      defaultValue: "DEFAULT2",
 *      dataLoadedObservable: self.loadedData
 *  });
 **/
ko.defferedLoadObservable = function (target, options) {
    options = $.extend({
        defaultValue: null,
        defferedLoadCallback: function () { throw "deffered Load Callback not provided!"; },
        dataLoadedObservable: null
    }, options || {});
    // If no value is provided for...