2

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 atag 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

1

1 Answer 1

5

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 format
  • args: format args

Usage:

<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

Sign up to request clarification or add additional context in comments.

1 Comment

Awesome, spot on what I wanted :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.