Reputation: 3616
In WPF there is a binding that I use a lot;
<GridViewColumn DisplayMemberBinding="{Binding Path=Price, StringFormat=Now {0:c}!}"/>
Is there a good way to achieve a similar binding in knockout? I'm using a sprintf library which would be great to utilize.
I guess I can create a custom binding for this, but this should be a rather common request so I thought I'd check here before trying to re-invent the wheel.
One use case is to build a href
attribute of an a
tag dynamically, e.g. to produce something like this:
<a href="#products/1/product/2">Foo</a>
Where 1 is the product group and 2 is the id of a product
Upvotes: 2
Views: 3700
Reputation: 47978
Because you want to format a value for display (ui) and to follow its changes, a custom binding that calls your sprintf library is the most suitable solution, which offers reusability also, for example:
ko.bindingHandlers.sprintf = {
update: function(element, valueAccessor) {
var options = valueAccessor();
var formatted = sprintf(ko.unwrap(options.format),
ko.unwrap(options.args).map(function(arg) {
return ko.unwrap(arg);
});
if(options.attr) {
element.setAttribute(options.attr, formatted);
} else {
element.textContent = formatted;
}
}
}
where this custom binding require a config object having the following properties:
attr
: the attribute to update (null if the text content of the element is to update)format
: string formatargs
: format argsUsage:
<a data-bind="sprintf: { attr:'href',
format:'#products/%0/product/%1',
args: [val1, val2] }">
click
</a>
// val1 & val2 are ko observables
But you can also use sprintf
directly within the data-bind
:
<a data-bind="attr: { href: sprintf('#products/%0/product/%1',
[val1(), val2()])
}">
click
</a>
Demo: JSFiddle
Upvotes: 5