Knockout.js ko.applyBindings() hierarchy binding

http://stackoverflow.com/questions/9256938/knockout-js-ko-applybindings-hierarchy-binding

by kougiland

HTML

<script src="http://knockoutjs.com/downloads/knockout-2.0.0.js"></script>
<div id="content" data-bind="with: content">
    <nav>
        <a href="" data-bind="click: go_to_books">Books</a>
        <a href="" data-bind="click: go_to_about">About</a><br/>
    </nav>

    <div id="books" data-bind="with: $root.books, visible: state() === 'books'">

        <input type="text" data-bind="value: new_book().name"/>
        <button data-bind="click: addBook">Add book</button>

        <h2>Books</h2>

        <ul data-bind="foreach: books">
            <li><span data-bind="text: name"></span></li>
        </ul>

    </div>

    <div id="about" data-bind="with: $root.about, visible: state() === 'about'">
        <p>About</p>
    </div>
</div>

JavaScript

$(document).ready(function () {

    function Book(name) {
        var self = this;

        self.name = ko.observable(name);
    }

    function BooksViewModel() {
        var self = this;

        self.new_book = ko.observable(new Book(""));

        self.books = ko.observableArray([
        ]);

        self.addBook = function () {
            self.books.push(self.new_book());
            self.new_book(new Book(""))
        }
    }

    function AboutViewModel() {
        var self = this;
    }

    function AppViewModel() {
        var self = this;

        self.state = ko.observable();

        self.go_to_books = function() { self.state("books"); };
        self.go_to_about = function() { self.state("about"); };
    }
            
    var main = {
            content: new AppViewModel(),
            books: new BooksViewModel(),
            about: new AboutViewModel()
    };
                                        
    ko.applyBindings(main);

});