Binding sample

by uedatakuya

HTML

<script src="http://cloud.github.com/downloads/SteveSanderson/knockout/knockout-2.1.0.js"></script>
Foo: <input data-bind="value: foo"/>
Bar: <input data-bind="value: bar"/>

JavaScript

var observer = (function() {
    
    var observables = [];
    
    return {
        find: function(o) {
            var i;
            for (i=0; i<observables.length;i++) {
                if (o === observables[i].observable) {
                    return observables[i];
                }
            }
        
            return null;
        },
        findByComputed: function(c) {
            var i;
            var found = [];
            for (i=0; i<observables.length;i++) {
                if (c === observables[i].computed) {
                    found.push(observables[i]);
                }
            }
        
            return found;
        },
        regist: function(o, c) {
            var ob = {               
                observable: o,
                computed: c,
                dependencies: []
            };
            observables.push(ob);
    
            // 依存関係を登録するために、一度呼ぶ    
            c();
    
            return ob;   
        },
        notify: function(o) {
            var ob = this.find(o);
            var i, d, dob;
            if (ob === null) {
                return;
            }

            for (i=0; i< ob.dependencies.length; i++) {
                d = ob.dependencies[i];    
                dob = this.find(d);                
                if (dob !== null) {                    
                    d(dob.computed());
                }
            }    
        }
    };
})();

var observable = function(init, computed) {
    var value = init;
    var firstCall = true;
    
    function property(v) {
        
        var ob, i, dependencies;
        
        if (firstCall) {
            
            ob = observer.find(property);
            dependencies = observer.findByComputed(property.caller);
            for (i=0; i<dependencies.length; i++) {
                ob.dependencies.push(dependencies[i].observable);
            }
            
            firstCall = false;
        }
        
        if (v !== void 0) {
   ...