HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

knockout binding handler for custom components

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
knockoutcustomcomponentsforbindinghandler

Problem

I am using a combination of knockoutJS and jQuery. I have a number of jQuery plugins which perform particular re-usable functions, such as a numeric spinbox.

I have written a binding handler to allow me to bind an observable property to the spinbox, it looks like this:

ko.bindingHandlers.spinbox = {
    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
        var value = valueAccessor();
        $(element).spinbox({
            min: value.min === undefined ? -5 : ko.unwrap(value.min),
            max: value.max === undefined ? 5 : ko.unwrap(value.max),
            scale: value.scale === undefined ? 2 : ko.unwrap(value.scale),
            step: value.step === undefined ? 0.1 : ko.unwrap(value.step),
            bigStep: value.bigStep === undefined ? 0.5 : ko.unwrap(value.bigStep)
        }).change(function() {
            value.data(parseFloat($(this).val()));
        });
    },
    update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
        var value = valueAccessor();
        var valueUnwrapped = ko.unwrap(value.data);
        $(element).val(valueUnwrapped.toFixed(1));
    }
};


and requires the binding to be set up something like:

data-bind="spinbox: {data: myProperty, min: -100, max: 100}"


As you can see, I have used the object notation to sent multiple parameters to the binding (min, max etc) - this is similar to the syntax that the knockout template binding uses. However I am not sure this is a sensible way to do this. Should I have instead used allBindings and passed these along as separate values like:

data-bind="spinbox: myProperty, min: -100, max: 100"


I am interested in opinions on complex knockout custom bindings.

Solution

I like your approach much better than using separate values.

The code reads really well, I only have 1 minor suggestion.

If you had a helper function like this:

function unwrapOrDefault( gift , defaultValue )
{
    return gift === undefined ? defaultValue : ko.unwrap( gift ), 
}


then you could have

min: unwrapOrDefault(value.min, -5),
        max: unwrapOrDefault(value.max, 5 );
        scale: unwrapOrDefault(value.scale, 2);
        step: unwrapOrDefault(value.step, 0.1);
        bigStep: unwrapOrDefault(value.bigStep, 0.5);

Code Snippets

function unwrapOrDefault( gift , defaultValue )
{
    return gift === undefined ? defaultValue : ko.unwrap( gift ), 
}
min: unwrapOrDefault(value.min, -5),
        max: unwrapOrDefault(value.max, 5 );
        scale: unwrapOrDefault(value.scale, 2);
        step: unwrapOrDefault(value.step, 0.1);
        bigStep: unwrapOrDefault(value.bigStep, 0.5);

Context

StackExchange Code Review Q#40970, answer score: 4

Revisions (0)

No revisions yet.