knockout-classBindingProvider

https://github.com/rniemeyer/knockout-classBindingProvider

by gurkavcu

HTML

<script src="http://cloud.github.com/downloads/SteveSanderson/knockout/knockout-2.1.0.js"></script>
<script src="http://cloud.github.com/downloads/rniemeyer/knockout-classBindingProvider/knockout-classBindingProvider.min.js"></script>
<div id="content">
    Editable: <input type="checkbox" data-class="editable" />
    <ul data-class="items">
        <li>
            <input data-class="edit enabled" />
            <button data-class="delete enabled">Delete</button>
        </li>
    </ul>
    <button data-class="add enabled">Add Item</button>

    <hr/>

    <!-- ko class: items -->
    <div data-class="view"></div>
    <!-- /ko -->
</div>

<hr/>

<div id="stats">
    <ul data-class="stats">
        <li>
            <span data-class="stat"></span>:
            <span data-class="count"></span>
        </li>
    </ul>
</div>

JavaScript

(function(ko) {
    //create an object that holds our bindings
    var bindings = {
        editable: function() {
            return { checked: this.editable };
        },
        //this is an example of a binding tht is shared across scopes and fields
        enabled: function(context) {
            return { enable: context.$root.editable };
        },
        items: function() {
            return { foreach: this.items };
        },
        edit: function() {
            return { value: this.name };
        },
        delete: function(context) {
            return { click: context.$parent.deleteItem };
        },
        add: function() {
            return { click: this.addItem };
        },
        view: function() {
            return { text: this.name };
        }
    };

    //just a quick example of adding some logging to the bindings
    var log = [];

    var instrumentBinding = function(prop, binding, log) {
        var stats = { count: ko.observable(0), prop: prop };
        log.push(stats);
        return function(context) {
            setTimeout(function() { stats.count(stats.count() + 1); }, 0);
            return binding.call(this, context);
        };
    };

    //wrap the bindings in a version that adds some instrumentation
    for (var prop in bindings) {
        if (bindings.hasOwnProperty(prop)) {
            bindings[prop] = instrumentBinding(prop, bindings[prop], log);
        }
    }

    //add some bindings for the stats (that are not instrumented themselves)
    bindings.stats = function() { return { foreach: this } };
    bindings.stat = function() { return { text: this.prop } };
    bindings.count = function() { return { text: this.count } };

    //tell Knockout that we want to use an alternate binding provider
    ko.bindingProvider.instance = new ko.classBindingProvider(bindings);

    var Item = function(name) {
        this.name = ko.observable(name);
    };

    var ViewModel = function(items) {
        var self = this;

     ...