Unobtrusive Knockout

2019-03-08 10:16发布

问题:

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?

回答1:

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.



回答2:

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/



回答3:

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.



回答4:

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.



回答5:

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".