I've recently got up to speed with Knockout and I think it's a fantastic framework. However I have one concern.
I'm finding that in non-trivial binding cases, I have snippets of javascript code creeping into my view (markup). In fact quite a few code samples in the Knockout documentation demonstrate this too.
Does this make Knockout inherently obtrusive?
Should I just accept it for what it is and not be worried in practice?
Or are there any patterns/techniques I should be employing to make Knockout unobtrusive?
Great question. I've been writing complex KnockoutJS views for awhile and was never satisfied until I switched to Ryan Niemeyer's class binding provider.
The Knockout ClassBindingProvider allows you to declare your bindings in a JavaScript object and then reference them from a data-class
attribute similar to how css classes work. It works great!
See an example TodoMVC app.
Try to keep Javascript out of the bindings and only use it for metadata
so instead of doing
<span data-bind="visible: errors().length > 0">You have errors</span>
Use a computed observable
<span data-bind="visible: hasErrors">You have errors</span>
Update: I went ahead and created a Convention over configuration API for KO
It can be found here https://github.com/AndersMalmgren/Knockout.BindingConventions/wiki
Instead of doing <button data-bind="click: save">Save</button>
you're doing <button data-name="save">Save</button>
. The library will understand by convention that you want to hookup the save function to the button click handler. By convention it will also bind enable if a canSave member is present.
http://jsfiddle.net/3Ajnj/15/
Should I just accept it for what it is and not be worried in practice?
My understanding is that "unobtrusive" means a few different things.
One aspect of "unobtrusive" is that websites should maintain core functionality on browsers with limited JavaScript support or none at all. To that end, your concern for this principle should depend on your target audience. I've worked on projects where I knew my target audience well enough that I had the luxury of saying, "if you want to take advantage of this web app, use a modern browser like Chrome, with JavaScript enabled." In this case, feel free to go buck wild with the latest, awesomest front-end frameworks out there.
I've worked on other projects where this was not the case we had to be very careful with our usage of frameworks like Knockout. If you're relying heavily on Knockout to do core functionality in your application, then your application is inherently obtrusive. Whether or not this should bother you depends on your target audience.
Another principle of "unobtrusive JS" is a separation of concerns between JavaScript and HTML. I actually debate how strictly important this principle is. I think a more important principle is a separation of concerns between view model logic and display logic, following the MVVM pattern. Knockout does a fantastic job of encouraging clean separation of view/vm concerns, even if you put a bit of JavaScript logic in your data bindings. As long as it's strictly view logic, I think it actually belongs in the view.
I recommend you, that you pay a visit to Ryan's blog and read: "Simplifying and Cleaning Up Views in KnockoutJS", if you haven't done so...
http://www.knockmeout.net/2011/08/simplifying-and-cleaning-up-views-in.html
It explains some nice ways for you to refactor your code, so it doesn't clutter the html and keep it more clean.
An alternative, to the binding provider suggested in the selected answer, is the knockout.unobtrusiveBindingProvider, which is "an unobtrusive, convention-based binding provider for Knockout JS that enables a clean separation of HTML and Knockout databindings".