In knockout.js we can use css binding for static classes
<div data-bind="css: {'translucent ': number() < 10}">static dynamic css classes</div>
and dynamic
<div data-bind="css: color">static dynamic css classes</div>
I've tried http://jsfiddle.net/tT9PK/1/ to combine it in something like
css: {color, translucent: number() < 10}
to get dynamic class color
and static translucent
at the same time, but I get an error. Is there a way to do that?
I'd create the
css
binding value in your viewmodel. You can define acomputed
that returns either an object or string.Some examples, using ES2015:
Correct...and to launch you even further, check out this modification.
http://jsfiddle.net/Fv27b/2/
Here, you'll see that not only are we combining the options, but we're creating our own binding entirely...which results in a much more portable extension of not just this view model, but any view model you may have in your project...so you'll only need to write this one once!
To invoke this, you just use it as a new data-bind property and can include as many (or as few) options as possible. Under this specific condition, I might have just provided $data, however if you're wanting a reusable option you need to be more specific as to what data types you need as parameters and not all view models may have the same properties.
Hope this does more than answer your question!
If you really get into complicated styling case, just accumulate all in the computed property. You can do it as Alex mentioned or a bit more readable:
the main drawback is that you're moving a part of view definition into the viewmodel, that should be more independent. The alternative is to provide all the logic above as a plain js function call, and let knockout evaluate it.
There is a more elegant solution to this problem via computed property names (for FF>34, Chrome, Safari>7.1):
Whereas
color
is a property with a string value.If the value of
color
is an observable then we need to clear the classname before that observable updates. If we do not do this then each change will add another class and not remove the previous one. This can easily be accomplished manually but I wrote an extender for those who are interested.With this extender, your JavaScript code would look like this:
And your markup would be this simple:
I have a code pen demonstrating this technique: http://codepen.io/USIUX/pen/WryGZQ
I have also submitted an issue with knockout in hopes that one day the custom extender will not be necessary: https://github.com/knockout/knockout/issues/1990
I solved this problem a while back by just cloning the
css
binding ascss2
.Normally you can't use the same binding handler twice in a data-bind attribute, so this allowed me to do the following:
I can't quite decide whether I still prefer this, or @Aleksey's answer, but this may be the only choice if you have multiple dynamic classes to add.
Nice question, the problem seems to be the binding
css
isn't thought to mix the two kinds,color(): color() != ''
doesn't work (would be nice).I like @Simon_waver's answer approach, simple and practical.
Maybe at the time of the question wasn't supported (Idk) but with current knockout also combining the classes works:
data-bind="css: computed"