Radom Greeting Demo - Knockout subscribe to model

by Nikolai L'Estrange

HTML

<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/3.0.0/knockout-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
<h1>Radom Greeting Demo</h1>
<h2>Subscribe to all changes of an entire Knockout ViewModel</h2>
Knockout is amazing. It is fast and intuitive. I use the subscribe function a lot, but I found myself lacking a general subscribe that allows me to track the changes of an entire ViewModel, so I created one myself that even supports unsubscribe and throttling.
<br/>
<br/>Check for more info:
<br/> <a href="http://keestalkstech.com/2014/04/subscribe-to-entire-knockout-viewmodel">http://keestalkstech.com/2014/04/subscribe-to-entire-knockout-viewmodel</a>

<br/>
<br/>Name:<span data-bind="text:name"></span>
<br/>Message:<span data-bind="text:message"></span>
<br/>Color:<span data-bind="text:color"></span>
<br/>
<br/>
<br/>

CSS

body, html {
    font-family:Arial;
    font-size:11px;
}
h1 {
    font-size:1.5em;
}

h2 {
    font-size:1.3em;
}
div {
    display:inline-block;
    padding:10px;
    margin:10px;
    font-family:Arial;
    border-radius:3px;
    font-weight:bold;
}

JavaScript

//initialize the knockout stuff
init();

//definition of the ViewModel:
function Greeter() {
    var _this = this;

    this.color = ko.observable('red');
    this.name = ko.observable('World');
    this.message = ko.observable('Hello');
    this.line = ko.computed(function () {
        return _this.message() + ' ' + _this.name() + '!';
    });
}

//create viewmodel
var vm = new Greeter();

//apply bindings
ko.applyBindings(vm);

//subscribe to change - add message when a 
//change of the view model occurs. Throttle
//it by 500ms:
ko.subscribe(vm, function (vm,changed) {
    var $div = $('<div></div>').text(changed+ ': ' + vm.line());
    $div.css({
        color: vm.color(),
        border: 'solid 3px ' + vm.color()
    });

    $('body').append($div);

    $div.fadeOut(5000);
}, 500);

//change it by hand:
vm.message('This is a ');
vm.name('Test Message');

//some arrays with data
var colors = ['red', 'green', 'purple', 'orange', '#F7A'];
var names = ['World', 'NSA', 'Kees', 'Earth', 'Moon', 'Visitor'];
var messages = ['Hello', 'Welkom', 'Goede morgen', 'Bye', 'Bazinga'];

//create a new random message every two seconds
window.setInterval(function () {
    
    //randomize the time it will show:
    var i = Math.floor(Math.random() * 10) * 1000;   

    //show message
    window.setTimeout(function () {
        var j = Math.floor(Math.random() * 3);
        switch(j){
         case 1:
            vm.color(colors[Math.floor(Math.random() * colors.length)]);
            break;
         case 2:
            vm.name(names[Math.floor(Math.random() * names.length)]);
            break;
         case 3:         
        		vm.message(messages[Math.floor(Math.random() * messages.length)]);
            break;
        }
        
    }, i);
}, 1000);

//init function for readability
function init() {

    (function () {

        //stores the subscriptions
        var subscriptions = [];

        //maintains a unique identifier 
        var id = 0;

        ko.subscribe =...