#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.

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 them using constructor options like 'keys' or 'excludes' to limit the attributes which have kb.Observables for them or 'requires' to ensure that observables are created consistently irregardless of the Model.

In this case, Knockback will skip creating an observable for the 'id' attribute:

view_model = kb.viewModel(new Backbone.Model({id: 20, name: 'Bob'}), {keys: ['name']})
var view_model = kb.viewModel(new Backbone.Model({id: 20, name: 'Bob'}), {keys: ['name']});

In this case, even if the 'date' attribute doesn't exist, Knockback will create both 'name' and 'date' observables:

view_model = kb.viewModel(new Backbone.Model({name: 'Bob'}), {requires: ['name', 'date']})
var view_model = kb.viewModel(new Backbone.Model({name: 'Bob'}), {requires: ['name', 'date']});

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 such as 'friend().name' below.

<div id='kbvm_bb_model'>
  <p>
    <span>First Person: </span>
    <input class='input-small pull-right' data-bind="value: name, valueUpdate: 'keyup'"/>
  </p>
  <p>
    <span>Second Person: </span>
    <input class='input-small pull-right' data-bind="value: friend().name, valueUpdate: 'keyup'"/>
  </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>
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])
var ko = kb.ko;

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

var 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.

<div id='kbvm_bb_collection'>
  <p>
    <span>First Person: </span>
    <input class='input-small pull-right' data-bind="value: name, valueUpdate: 'keyup'"/>
  </p>
  <p>
    <span>Second Person: </span>
    <input class='input-small pull-right' data-bind="value: friends()[0].name, valueUpdate: 'keyup'"/>
  </p>
  <p>
    <span>Third Person: </span>
    <input class='input-small pull-right' data-bind="value: friends()[1].name, valueUpdate: 'keyup'"/>
  </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>
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])
var ko = kb.ko;

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

var 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: