In Part 1 of this series I discussed the basics of data binding in KnockoutJS. In this post, I’ll dive a little deeper in the the binding behaviors of KnockoutJS and show how you can build really responsive web apps using client side development techniques.
The essence of a Presentation Model is of a fully self-contained class that represents all the data and behavior of the UI window, but without any of the controls used to render that UI on the screen. A view then simply projects the state of the presentation model onto the glass.
As Fowler explains, the Presentation Model class should represent both the data and the behavior which are then bound to the view. Let’s dive into how KnockoutJS handles binding behaviors to your HTML.
In MVVM applications users are interacting directly with the view. The view is responsible for displaying data and accepting user input. In HTML, this input will generate events which I can then use to trigger some logic. In the example below I have added a button to my previous example. When I click the button, I want the app to greet the user.
KnockoutJS solves this problem very cleanly using the data-bind attribute that we looked at previously. KnockoutJS includes three bindings that allow me to bind standard HTML events.
|Binding ||Description |
|event ||This binding adds event handlers for the specified events to the associated DOM element. You can use this to bind to any defined HTML events. Within your event handler you can access the current view model data item, the event object or even custom parameters passed as part of the event binding. |
|click ||This binding is a shortcut for handling the click event. |
|submit ||This binding is a shortcut for handling the submit event for the form element. |
The previous example can be refactored to use the KnockoutJS click event binding.
Alternatively I could have written this using the generic event binding. In addition to using the generic event binding, I also took advantage of the data and event objects which get passed as part of the event handler parameters.
While event and data binding are pretty simple and straightforward there will be occasions where you want to create your own binding types. Maybe you want to create a shortcut binding to handle the Change or Focus events or maybe you want to create a binding which wraps a set of events with a custom behavior. All of this and more is possible with custom bindings. In fact all of the event and data bindings that I previously discussed are just bindings that are defined in the core KnockoutJS library but the methods used by the core library are exactly the same methods you’ll use to create your own bindings.
As a real world example, I often find that when using multi-line text editors that use a lot of screen real-estate for the text editor in order to have a nice editing experience. However, when my focus is on other form fields I don’t really need to use all that space. In one project I wanted to expand the text editor only when it had focus.
The init binding method is used for setting the initial state of the DOM elements and also for setting up an event handlers that might be needed to implement the behavior. As you can see in this case, I was the system to make certain UI changes whenever the element receives or loses focus. Based on these events I update the view model to reflect whether I am currently editing the field or not. When the view model biography.editing value changes as a result of the focus and blur events, then KnockoutJS will call the update method.
The update method is used for adding more complex binding logic to an element than you could do with standard bindings. For example, if I was only changing the CSS for the binding element, then I wouldn’t really need to use the update method. Instead I could use a style binding with a simple expression to determine whether I was currently editing the biography element or not. Your custom binding does not have to include both the init and update methods. Use one or both as it makes sense for your binding.
KnockoutJS bindings are an incredibly powerful mechanism for building client-side functionality. At this point you should have a basic understanding of how both data and behavior binding works within KnockoutJS. In the next post of this series I’ll take a look at control flow bindings available in KnockoutJS and show how those bindings can be used for even greater control. The control flow bindings are an integral part of the templating story which is a key part of any client side development toolkit.
This article is cross-posted from my personal blog.