In custom bindings you can pass whole object, parse it and later use it, also you can pass a function (like observable for example).
HTML
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script type="text/javascript" src="/knockout-3.3.0.js"></script> <script type="text/javascript" src="/index.ko.extension.js" defer></script> <script type="text/javascript" src="/index.js" defer></script> </head> <body> <div data-bind="myBind: {propertyOne: testOne, propertyTwo: testTwo}"></div> </body> </html>
Here notice part:
<div data-bind="myBind: {propertyOne: testOne, propertyTwo: testTwo}"></div>
Now index.js:
/*global window, ko*/ function MyLog(msg) { function doTheLog(msg) { console.log(msg); } return { doTheLog: doTheLog } }; window.doSomething = new MyLog(); window.testOne = "test one"; window.testTwo = "test two"; ko.applyBindings();
Here notice that I have created global variables testOne and testTwo, I need them for binding.
index.ko.extension.js:
/*global ko, console*/ /*jslint unparam: true*/ ko.bindingHandlers.myBind = { init: function (element, valueAccessor) { "use strict"; var myObjExample = ko.unwrap(valueAccessor()); doSomething.doTheLog(myObjExample.propertyOne); doSomething.doTheLog(myObjExample.propertyTwo); } }; /*jslint unparam: false*/
Here notice:
var myObjExample = ko.unwrap(valueAccessor());
With that I am actually parsing my object.
Unit test looks like this:
/*global describe, it, expect, beforeEach, ko, window, document, $*/ describe("my bind", function () { "use strict"; var sut; beforeEach(function () { //'<div data-bind="myBind: {propertyOne: testOne, propertyTwo: testTwo}"></div>' var myDiv = document.createElement('div'); myDiv.setAttribute("data-bind", "myBind: {propertyOne: testOne, propertyTwo: testTwo}"); document.body.appendChild(myDiv); window.testOne = "test one"; window.testTwo = "test two"; window.doSomething = jasmine.createSpyObj('MyLog', ['doTheLog']); ko.applyBindings(); }); it("gets object from value acessor", function () { expect(window.doSomething.doTheLog).toHaveBeenCalled(); }); });
Example download from here.
---
Actually, better unit test looks like:
/*global describe, it, expect, beforeEach, ko, window, document*/ describe("my bind", function () { "use strict"; var sut, testOne, testTwo; beforeEach(function () { var myDiv = document.createElement('div'); testOne = jasmine.createSpy("testOne"); testTwo = jasmine.createSpy("testTwo"); myDiv.setAttribute("data-bind", "myBind: {testOne: testOne, testTwo: testTwo}"); document.body.appendChild(myDiv); window.doSomething = jasmine.createSpyObj('MyLog', ['doTheLog']); ko.applyBindings({testOne: testOne, testTwo: testTwo}); }); it("gets object from value acessor", function () { expect(window.doSomething.doTheLog).toHaveBeenCalled(); }); });
Notice first my binding:
myDiv.setAttribute("data-bind", "myBind: {testOne: testOne, testTwo: testTwo}");
Then the apply bindings:
ko.applyBindings({testOne: testOne, testTwo: testTwo});
Version with this test download from here.