Exercises dynamic application of a template

Illustrates problem with de-referencing $parent in a template

HTML

<script src="https://github.com/downloads/SteveSanderson/knockout/knockout-2.0.0.js"></script>
<script id="test" type="text/html">
    <div>
        <div data-bind="text: title"></div>
        <button data-bind="assess: $parent.assess, value: {obj: $data, assessment: 'good'}">Thumbs up</button>
        <button data-bind="assess: $parent.assess, value: {obj: $data, assessment: 'bad'}">Thumbs down</button>
    </div>
</script>


<div data-bind="template: {name: 'test', data: doc1}"></div>
<div data-bind="template: {name: 'test', data: doc2}"></div>

<div data-bind="dynamic: doc1"></div>
<div data-bind="dynamic: doc2"></div>

JavaScript

ko.bindingHandlers.assess = {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel) {
        $(element).click(function() {
            var parentFcn = ko.utils.unwrapObservable(valueAccessor());
            console.log(valueAccessor());
            var value = allBindingsAccessor().value;
            parentFcn(value);
        });
    }
};
ko.bindingHandlers.dynamic = {
    update: function(element, valueAccessor, allBindingsAccessor, doc) {
        var doc = ko.utils.unwrapObservable(valueAccessor());
       // console.log(doc);
        ko.renderTemplate('test', doc, {}, element, 'replaceNode');
    }
};

function Document(title) {
    var self = this;
    this.title = ko.observable(title);
    
    this.toString = function() { return 'Document "' + self.title() + '"'; };
};

var vm = new function() {
    var self = this;
    
    this.doc1 = ko.observable(new Document('doc 1'));
    this.doc2 = ko.observable(new Document('doc 2'));
    this.assess = function(v) {
        alert(v.obj + ' is ' + v.assessment);
    };
};

ko.applyBindings(vm);