Knockout 2.0.0 is Available
Knockout 2.0.0 was released last night to the web! You might have been tinkering with the 1.3.0 RC recently, but it has been renamed to 2.0.0. Steve lists a few reasons why he went this route and I fully support the decision to jump to a new major version number. If you look inside to see what he added and changed for KO v2.0.0 you will see a pretty dramatic and powerful set of improvements.
I have to thank Steve for creating and keeping up with the community requests for KO. He has been especially helpful to me in creating my upcoming series in MSDN Magazine on Knockout and my Pluralsight course, both of which should be out starting in February and are updated for KO 2, so please keep an eye out for them!
First let’s cover the important links, then let’s hit some of the best new features.
Links that have been fully updated for Knockout 2.0.0 are the builds on GitHub, the tutorials , and the documentation and live examples . And of course, Steve’s post that summarizes everything you need to know. Many community folks contributed to this release and some even wrote documentation.
Here are my top 5 features in KO 2:
(I linked to Steve’s JSFiddle examples for many of these. Just click on the keywords below to see examples.)
<h3>1. Control of flow bindings</h3> <p>This is where you can use built in bindings for if, ifnot, foreach, and with inside of elements or even containerless tags … more on that in a moment. (I linked directly to Steve’s examples on JSFiddle). Excellent new feature that I use every day.</p> <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><ul data-bind=”foreach: products”>
<li>
<strong data-bind=”text: name”></strong>
<em data-bind=”if: manufacturer”>
— made by <span data-bind=”text: manufacturer.company”></span>
</em>
</li>
</ul></pre>
</div>
2. Containerless control of flow
</strong>
Another killer feature. Sometimes you may need to control the flow of your bindings or templates. Knockout 2.0.0 adds the ability to use HTML comments to wrap control of flow bindings. I really love this feature as it helps me clean up my HTML and avoid having an element for no reason other than control of flow (which I had to do occasionally with KO 1.2)
<!-- ko foreach: customers -->
<div data-bind="text: companyName"></div>
<!-- /ko -->
3. Parent binding contexts
</strong>
Can anyone say ancestor relative source bindings? Yeah, you XAML folks know what I mean. KO 2v2 makes it easy to navigate from inside of a template where the data context is one thing, and reference a data context higher up in the hierarchy. This is really important when you are inside of a template and you need to reference a different data context (like for a combobox). You can reference the root context ($root), get an array of parent contexts ($parents), get the immediately preceding parent context ($parent) too. This is one of those features that you don’t think about often, but when you need it … you REALLY need it. Otherwise, you write some funky workaround code.
4. Event handlers now receive the model as the first Parameter
This is pretty self explanatory … now when you bind to an event handler Knockout will automatically pass the model for the current data context to the handler. This makes it much simpler to write handlers that must operate on the current context (like remove, check selected, etc.) What’s even better here is that you don’t have to tell it to pass the context … it just does it under the covers and it keeps your HTML clean.
<button data-bind="click: $parent.removeProduct">Delete</button>
Breaking Change: Note that in previous version the event handler received the DOM event object as the first parameter. In KO v2, the event handler receives the model as the first parameter, and the DOM event object as the second parameter. You will need to change any KO code that uses the DOM event object to account for it as the second parameter.
// KO v1.2
myViewModel.myEventHandler = function(evt)
// KO v2
myViewModel.myEventHandler = function(data, evt)
5. jQuery style event handlers
Some folks don’t like putting the click handlers in their HTML bindings. So another new feature is to use jQuery style handlers for events handlers. This is straightforward to set up, but the added value here is from the ko.dataFor and ko.contextFor helper functions. Simply put, instead of passing the model into the handler, the handler itself can refer back to the context for the operation, or the data for (the model) the operation.
$(".prods").on("click", ".del", function() {
viewModel.removeProduct(ko.dataFor(this));
});
6. Native Templates
OK, so this is really my top 6 favorite new features in Knockout, but it’s a really good one. Knockout 2.0.0 adds support for native templates. What’s that? It means that you no longer have to take a dependency on jQuery templates nor any other external JavaScript templating library. You can check out the examples here for native templates, I highly recommend it!
If you want to continue using jQuery templates, you can do so. However KO 2 drops support for some of the older versions of jQuery templates. I won’t bore you with the details of how, because frankly, if you are using KO I think recommend moving to native templates and jQuery templates is no longer being actively developed.
What Else?
One other change that I almost missed my first time through it all is that there is a new function ko.computed. Actually, this is not a new function, it’s a new name for dependentObservable. Both names refer to the same function internally in KO, but the “new” way is to call them using ko.computed.