Tutorial: kb.ViewModel

Knockback.js has a helper called kb.ViewModel to automatically generate observables for each attribute

Most likely you will use the kb.viewModel(model) factory method to create a kb.ViewModel.

warning Unless you specify otherwise, a kb.ViewModel creates an observable for every attribute (including the id) which can cause performance issues on a page with many models. It is recommended to get started quickly with kb.ViewModels and then optimize with specialized classes like kb.Observable and kb.CollectionObservable.

Attribute Type: Backbone.Model

If Knockback encounters a attribute that is a Backbone.Model, it automatically creates a kb.ViewModel for it. Because the model can change behind the scenes, you must access the view model using the 'attribute_name()' syntax rather than as a simple property.

Views:

<div id='kbvm_bb_model'>
  <p>
    <span>First Person: </span>
    <input data-bind="value: name"/>
  </p>
  <p>
    <span>Second Person: </span>
    <input data-bind="value: friend().name"/>
  </p>

  <p>
    <span>Person: </span>
    <span data-bind="text: name"></span>
  <p>
    <span>Has this friend: </span>
    <span data-bind="text: friend().name"></span>
  </p>
</div>

ViewModel and Bindings:

bob = new Backbone.Model({name: 'Bob', friend: new Backbone.Model({name: 'Fred'})})

view_model = kb.viewModel(bob)

ko.applyBindings(view_model, $('#kbvm_bb_model')[0])
// Generated by CoffeeScript 1.3.3
var bob, view_model;

bob = new Backbone.Model({
  name: 'Bob',
  friend: new Backbone.Model({
    name: 'Fred'
  })
});

view_model = kb.viewModel(bob);

ko.applyBindings(view_model, $('#kbvm_bb_model')[0]);

Live Result

First Person:

Second Person:

Person:

Has this friend:

Attribute Type: Backbone.Collection

If Knockback encounters a attribute that is a Backbone.Collection, it automatically creates a kb.CollectionObservable for it and a kb.ViewModel for each of it's models. Because the collection can change behind the scenes, you must access the collection observable using the 'attribute_name()' syntax rather than as a simple property.

Views:

<div id='kbvm_bb_collection'>
  <p>
    <span>First Person: </span>
    <input data-bind="value: name"/>
  </p>
  <p>
    <span>Second Person: </span>
    <input data-bind="value: friends()[0].name"/>
  </p>
  <p>
    <span>Third Person: </span>
    <input data-bind="value: friends()[1].name"/>
  </p>

  <p>
    <span>Person: </span>
    <span data-bind="text: name"></span>
  <p>
    <span>Has these friends: </span>
    <ul data-bind="foreach: friends">
      <li data-bind="text: name"></li>
    </ul>
  </p>
</div>

ViewModel and Bindings:

bob = new Backbone.Model({name: 'Bob', friends: new Backbone.Collection([new Backbone.Model({name: 'Fred'}), new Backbone.Model({name: 'John'})])})

view_model = kb.viewModel(bob)

ko.applyBindings(view_model, $('#kbvm_bb_collection')[0])
// Generated by CoffeeScript 1.3.3
var bob, view_model;

bob = new Backbone.Model({
  name: 'Bob',
  friends: new Backbone.Collection([
    new Backbone.Model({
      name: 'Fred'
    }), new Backbone.Model({
      name: 'John'
    })
  ])
});

view_model = kb.viewModel(bob);

ko.applyBindings(view_model, $('#kbvm_bb_collection')[0]);

Live Result

First Person:

Second Person:

Third Person:

Person:

Has these friends: