Knockout 3.3 is available now! This release features some nice refinements to the components functionality along with a number of other small enhancements and bug fixes. The full release notes can be found here.
In this release cycle, we welcomed Brian Hunt to the core team and he has brought some great energy and contributions to the project. Steve and Michael once again made the bulk of the major changes in this release along with a number of other pull requests from the community.
We received lots of great feedback regarding Knockout’s component functionality. Many developers seem to be having great success using this style of development. For 3.3, we focused on a few low-level enhancements that should provide some increased flexibility.
Components were always rendered asynchronously previously, even when the template/viewModel were already cached. Now, the component registration can include a “synchronous” flag to indicate that the component should render synchronously, if it can. In the case where you have many nested components, this can help alleviate issues with reflows and/or flickering while rendering. The syntax would look like:
1 2 3 4 5
Working with component child nodes
In Knockout 3.3, you now have options for working with the child nodes contained inside of a component. There are three enhancements that go together targetting this area:
template binding can accept an array of DOM nodes directly via a
2- If you are using a
createViewModel function for your component, it will now receive the child nodes and you can determine how to expose them on your component’s view model for binding against the template binding
1 2 3 4 5 6 7 8 9 10 11 12 13 14
3- There is a new
$componentTemplateNodes context variable that contains the nodes directly. In normal cases, this will allow you to avoid exposing DOM nodes in your view model and bind in the template directly.
For example, a component template might simply want to add some wrapping markup like:
You could then add the component to your page:
1 2 3 4 5
If would still be possible to manipulate (
$componentTemplateNodes directly in the binding, depending on the complexity of the markup/scenario.
$component context variable
Sometimes inside of a component’s template, when looping through nested structures, you may want to bind up to the root of the component. Rather than trying to manage
$parents[x], you can now use
$component to get the nearest components root. This is a similar concept to
$root for the entire application, but is specific to a component.
A few other enhancements that I think are interesting:
awake/sleep notifications from pure and deferred computeds
You can now subscribe to notifications from a
pureComputed for when it wakes up and for when it goes to sleep (when nothing depends on it). Additionally, a deferred computed now notifies when it wakes up as well. The subscriptions would look like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Exposing a few additional functions to the release build
ko.ignoreDependencies(callback, callbackTarget, callbackArgs)- executes a function and ignores any dependencies that may be encountered. This can be useful sometimes in a computed observable or in a custom binding when you want to execute code, but not trigger updates when any dependencies from that code change. You would use it like:
ko.utils.setTextContent(element, textContent)handles cross-browser setting the text of a node and handles virtual elements
3.3 also includes a number of nice fixes and performance improvements listed here. This includes making the
css binding work properly with SVG elements, which has been a long-standing issue.