After spending some time building my first production Angular app (which is great), the ngModel directive struck me as being immediately useful, compared to the traditional KnockoutJS workflow. So I replicated some of the behavior with a “lazy model” binding handler.

ngModel

The part that I found particuarly useful with ngModel is that it creates and exposes the model property to the UI for binding. Therefore, you can describe an observable model object that doesn’t exist yet, and it will be created for you.

<div ng-controller="Ctrl">
 	<input ng-model="name" type="text" class="my-input" />
 </div>
function Ctrl($scope) {
  //nothing here, but the name variable is created on the controllers $scope 
}

Knockout

Comparing this to knockout, you can see that you have to do a little more work to achieve the same result.

<input type="text" data-bind="value: name"/>
var vm =  {
	name: ko.observable();
}
ko.applyBindings(vm);

My main problem with the Knockout way, is that I have to describe my bindable model object in two places now, the view and the Viewmodel. To bring a little simplification to this process, I created a new binding handler to handle the implicit creation for me.

Lazy Model

<!-- ko model: {value:'name',target:model} -->
	<input type="text" data-bind="value: model.name"/>
<!-- /ko -->

<!-- ko model: {value:'address',target:model} -->
	<input type="text" data-bind="value: model.address"/>
<!-- /ko -->
var vm =  {
	model:{} //empty model that view objects get lazily added to
}

In this example, you can think of the model object as being our $scope. Whenever you declare an observable to bind in the UI, it will get implicty created onto the model object as an observable value. In this way, you have only described your model properties in one place. An added bonus is a really clean viewmodel.

The best part about this particular implementation, is that is can even get complex, with property path syntax, e.g.

<!-- ko model: {value:'name',target:model} -->
	<input type="text" data-bind="value: model.name"/>
<!-- /ko -->

<!-- ko model: {value:'address.city',target:model} -->
	<input type="text" data-bind="value: model.address.city"/>
<!-- /ko -->

<!-- ko model: {value:'address.zip',target:model} -->
	<input type="text" data-bind="value: model.address.zip"/>
<!-- /ko -->

This would result in an object that on the viewmodel that looks like -

model:{
	name: ko.observable(),
	address: {
		city: ko.observable(),
		zip: ko.observable()
	}
}

What are the drawbacks with a pattern like this? This is most useful for simple form controls where you don’t need to access advanced observable functions like extenders, or manual subscriptions. You could still do those things, but since your model properties are being lazily created, you would have to modify the method with another way to access the lazily created values. This could be something like a callback with the key and observable value to bind subscriptions to.

<!-- ko model: {value:'name',target:model,onCreate:created} -->
      <label for="name">Name</label>
      <input required type="text" data-bind="value:model.name, valueUpdate: 'keydown'"/>
    <!-- /ko -->

Here is a gist of a working implementation, but feel free to modify and extend if you find it useful.