Version 3.2 of Knockout was released a few weeks ago and it introduces a major new feature: Components and Custom Elements. A big part of this new feature is the support for asynchronously loading views and view models via AMD.
Even if your app doesn't use AMD, the new component feature is worth the upgrade just to help deal with one of the biggest anti-patterns I see in large enterprise-y Knockout apps: templates for complex form fields with way too much logic in HTML.
Here's an example of a "Super Text Field" which does everything from tab indexes to validation to tooltips. It's implemented using the
template binding with many parameters which may or may not be used.
Notice the volume of logic in the HTML template, like adding "txt-" to the id and defaulting the tabindex, which cannot be unit tested and therefore become quite brittle.
With Knockout 3.2, we can use the
component binding instead to define a ViewModel (constructor function) for the HTML template and render it using a
<super-text-field> custom HTML element.
This may not seem very different but there are some big wins here:
- The logic has been moved out of the HTML and into a unit-testable SuperTextField ViewModel. Yay! This was possible before 3.2 with some different techniques but now it's out-of-the-box.
- The SuperTextField function can perform additional logic like throwing exceptions for missing parameters... whatever you want.
componentbinding provides a hook for calling the
disposefunction on the ViewModel whenever the matching element is disposed. Click the button and check our console for an example. This is extremely handy for things like disposing of subscriptions and clearing timeouts/intervals.
- Arguably more readable HTML
Please note that Knockout isn't forcing you to move your logic into JS. You can still have all that logic in your HTML if you really want and still use the
component binding because the
viewModel parameter in the component registration is optional. Hopefully though now that Knockout can construct ViewModels for you those messy HTML templates will be a thing of the past.
Check it out
component binding in 3.2 is highly configurable and is a great new addition to the library.