Edit in JSFiddle

//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) {
                    this.currentTmpl(fakeDataToRetrieveFromTheServer[this.key]);
                },
                error: function(data) {
                    this.currentTmpl(this.errorTmpl);  
                },
                dataType: 'json'
            });   
        }
    },
    //some defaults to use for the loading/error templates
    loadingTmpl: "<div><img src='http://rniemeyer.github.com/KnockMeOut/Images/loading.gif' /><div>" ,
    errorTmpl: "error!<br/>"
});

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

//define a new template engine that knows how to work with our new templateSource
function myExternalTemplateEngine(templates) {
   var result = new ko.nativeTemplateEngine();
   result.templates = templates;
   result.makeTemplateSource = function(templateName) {
        return this.templates[templateName];
   } 
   return result;
}

//------------------------------------------------------------------------------
                             
//actual page code
function Item(id, name) {
    return {
        id: ko.observable(id),
        name: ko.observable(name)
    }
}
var viewModel = {
    templates: {
        viewTemplate: new ko.ExternalTemplate("view"),
        editTemplate: new ko.ExternalTemplate("edit", "loading...<br/>", "error2")
    },
    isEditable: ko.observable(false),
    items: ko.observableArray([
        new Item(1, "one"),
        new Item(2, "two"),
        new Item(3, "three")
        ]),
    addItem: function() {
       this.items.push(new Item(0, "new"));   
    },
    whichTemplateToUse: function() {
        return viewModel.isEditable() ? 'editTemplate' : 'viewTemplate';
    }
};


//make this new template engine our default engine
ko.setTemplateEngine(new myExternalTemplateEngine(viewModel.templates));

ko.applyBindings(viewModel);
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>




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