Knockout Delay Loading Bindings

Attempting to delay load custom bindings in KnockoutJS

by IPWright83

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
<div data-bind="foreach: items">
    <div data-bind="dl-myCustomBinding: $data"></div>
</div>

JavaScript

function customBindingUrl(name) {
	return "https://jsfiddle.net/echo/js/?js=" +
        encodeURIComponent(
            'ko.bindingHandlers.' + name + ' = {' +
                'init: function () {' +
                    'return { controlsDescendantBindings: true };' +
                '},' +
                'update: function (element, valueAccessor) {' +
                    'var value = valueAccessor();' +
                    'var title = value.title();' +
                    '$(element).html("<p>" + title + "</p>");' +
                '}' +
	        '};');
}

var originalGetBindingHandler = ko.getBindingHandler;
ko.getBindingHandler = function (bindingKey) {
    // If the binding handler is already known about then return it now
    var handler = originalGetBindingHandler(bindingKey);
    if (handler) {
        return handler;
    }

    if (bindingKey.startsWith("dl-")) {
        bindingKey = bindingKey.replace("dl-", "");
        if (ko.bindingHandlers[bindingKey]) {
            return ko.bindingHandlers[bindingKey];
        }

        // Work out the URL at which the binding handler should be loaded
        var url = customBindingUrl(bindingKey);

        // Load the binding from the URL
        var loading = $.getScript(url);

        return ko.bindingHandlers["dl-" + bindingKey] = {
            init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
                // Once the binding is loaded, apply it to the element
                loading.done(function() { 
                    var binding = {};
                    binding[bindingKey] = valueAccessor;
                    ko.applyBindingAccessorsToNode(element, binding);
                });
                // Assumes that all dynamically loaded bindings will want to control descendant bindings
                return { controlsDescendantBindings: true };
            }
        }
    }
};

var vm = {};
vm.items = ko.observableArray();
ko.applyBindings(vm);

setTimeout(function () {
 ...