Arden Latraca
Arden Latraca

Reputation: 43

Knockout js passing parameters in click data-bind using knockout secure binding

I've tried to implement ksb on my knockout js but when passing params in onClick binding will result an error.

I used this line:

<button type="button" data-bind="click: btnClick.bind($data, '1')">button</button>

It will throw an error:

Uncaught #<Object> knockout-secure-binding.js: 440

How do I pass param on my onClick binding?

Upvotes: 2

Views: 1605

Answers (2)

WolfsMind
WolfsMind

Reputation: 1

I was able to get create a button which called a function passing in the current context data object as a parameter using the click binding as follows:

<div class="btn btn-default" data-bind="click: function() {$root.functionName($data)}">
    <!-- content -->
</div >

and with a property:

<div class="btn btn-default" data-bind="click: function() { $root.functionName($data.property)}">
    <!-- content -->
</div >

Upvotes: 0

Roy J
Roy J

Reputation: 43881

The documentation for ksb says (note particularly #3, bolding added):

The language used in KSB in bindings is a superset of JSON but a subset of Javascript. I will call it the sbind language, for convenience.

Sbind language is closer to JSON than Javascript, so it's easier to describe its differences by comparing it to JSON. The sbind language differs from JSON in that:

  1. it understands the undefined keyword;
  2. it looks up variables on $data or $context or globals (in that order);
  3. functions can be called (but do not accept arguments);
  4. top-level functions are called with this set to an object with the following keys: $data, $context, globals, $element, corresponding to the state for the respective element bound.

To get around this limitation, you can use a custom binding handler that wraps other custom binding handlers, and gives them a bound function.

ko.bindingHandlers.curry = {
    unwrap: function (valueAccessor, data) {
        var val = valueAccessor(),
            theFunction = data[val[1].token];
        return {
            bh: ko.bindingHandlers[val[0]],
            fnVa: function () {
                return theFunction.apply.bind(theFunction, theFunction, val.slice(2));
            }
        };
    },
    init: function (element, valueAccessor, allBindingsAccessor, data, context) {
        var spec = ko.bindingHandlers.curry.unwrap(valueAccessor, data),
            init = spec.bh.init;
        if (init) {
            init(element, spec.fnVa, allBindingsAccessor, data, context);
        }
    },
    update: function (element, valueAccessor, allBindingsAccessor, data, context) {
        var spec = ko.bindingHandlers.curry.unwrap(valueAccessor, data),
            update = spec.bh.update;
        if (update) {
            update(element, spec.fnVa, allBindingsAccessor, data, context);
        }
    }
};

Use it like so:

<button type="button" data-bind="curry:['click', btnClick, '1', '2']">short</button>

Demo fiddle.

Upvotes: 1

Related Questions