5
\$\begingroup\$

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.

\$\endgroup\$
4
\$\begingroup\$

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);
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.