Wednesday, September 2, 2015

Add on-the-fly bindings in knockout

Let's say you want to add a special css class that you only need in a certain context in a certain template.  Instead of defining the css class on the viewModel: this.extraCssClass = 'myClass'; Consider doing this:

<!-- ko with: function() { $context.extraCssClass = {'my-css-class': true}; return $data } -->
{{ my/sub/template.mustache }}
<!-- /ko -->

What is happening here is that we use the with binding to call a function that installs extraCssClass on $context.  Then we return $data to continue using the same $data scope with inner data-bind calls.

Then in template.mustache, you can consume the css class by checking $context:
<div data-bind="css: $context.extraCssClass || {}"></div>

I don't think this is *too* hacky, and it allows you inject custom variables without adding special logic to your viewmodel.
Let me know what you think!