Knockout: Object Output Concept

by andypotanin

HTML

<h3 data-bind="text: $data.name"></h3>
<pre data-bind="text: $data.content"></pre>
<div data-bind="text: $data.time"></div>

JavaScript

console.clear();

// Define our Constructor
var Socket = function (name) {
    var self = this;

    // Set new name via "set" wrapper
    self.set('name', name);

    // Update time every 2 seconds
    setInterval(function () {
        self.set('time', new Date().getTime());
    }, 2000);

}

Object.defineProperties(Socket.prototype, {
    'set': {
        'value': function (key, value) {

            value = ko.utils.unwrapObservable(value);

            // Convert objcts to strings
            if( 'object' === typeof value && Object.keys( value ) ) {
                value = JSON.stringify( value, null, 2 );
            }
            
            //console.log(key, ko.isObservable(this[key]) ? 'is' : 'is not', 'observable', typeof value, value);

            if (!ko.isObservable(this[key])) {
                return this[key] = ko.observable(value);
            } else {
                return this[key](value);
            }

        }
    },
        'ViewModel': {

        'get': function () {
            this.set('name', this.name);
            this.set('content', this.content);
            this.set('time', this.time || new Date().getTime());
            return this; // Vey important, must return context.
        }

    }
});

// Crate Sock Instance
var MySocket = window.MySocket = new Socket('DirtySock');

// Our ViewModel is a getter - no need to call "new" here
ko.applyBindings(MySocket.ViewModel);

MySocket.set( 'content', window.location );