external string templates in 1.3

sample of a template engine that uses a templateSource that retrieves its data via AJAX.

by namlth

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.5.0/knockout-min.js"></script>
Editable: <input type="checkbox" data-bind="checked: isEditable" />
<h2>string template</h2>
<ul data-bind="template: { name: whichTemplateToUse, foreach: items }"></ul>
<button data-bind="click: addItem">Add</button>

CSS

h2 { font-size: 1.1em; font-weight: bold; }

JavaScript

//simulate data that would be retrieved from server
var fakeDataToRetrieveFromTheServer = {
    view: "<li data-bind=\"text: name\"></li>",
    edit: "<li><input data-bind=\"value: name\" /></li>"
};


//------------------------------------------------------------------------------

//a templateSource that retrieves data via AJAX and provides loading/error templates
ko.ExternalTemplate = function(key, loadingTmpl, errorTmpl) {
    this.key = key; 
    this.loaded = false;
    this.inProgress = false;
    
    //templates to use while loading and when an error happens.  fall back to a default.
    this.loadingTmpl = loadingTmpl || this.loadingTmpl;   
    this.errorTmpl = errorTmpl || this.errorTmpl;
    
    //the current template
    this.currentTmpl = ko.observable(this.loadingTmpl);
    this.currentTmpl.data = {};  //a place to tuck away meta-data about the template
};

ko.utils.extend(ko.ExternalTemplate.prototype, {
    //read/write meta-data about the template (has it been rewritten already; not used for native templates currently)
    data: function(key, value) {
        if (arguments.length === 1) {
           return this.currentTmpl.data[key];   
        } 
        this.currentTmpl.data[key] = value;
    },
    //read/write the actual template text 
    text: function(value) {
        if (!this.loaded) {
           this.getTemplate();   
        }
        
        if (arguments.length === 0) {
            return this.currentTmpl();            
        } else {
           this.currentTmpl(arguments[0]);
        } 
    },
    //retrieve our actual template via AJAX
    getTemplate: function() {
        if (!this.inProgress) {
            this.inProgress = true;
            $.ajax({
                type: 'POST',
                url: '/echo/json/',
                data: {
                    json: ko.toJSON({ key: this.key }),
                    delay: 1
                },
                context: this,
                success: function(data) {
            ...