How to create knockoutjs custom binding in Magento 2

Magento 2 uses knockoutjs for rendering UI component. Today I will discuss how you can use existing knockoutjs binding and how you can create a new binding.

What is binding?
Binding or a data binding is a way to link your ViewModels to your Views and vice versa.

What custom bindings are available in knockoutjs?
Magento 2 uses all default knockoutjs bindings and uses some custom bindings too. Most important binding is scope binding. You can read all custom bindings from devdocs. All custom bindings under /vendor/magento/module-ui/view/base/web/js/lib/knockout/bindings

How to use?

Check the scope binding example:

<div class="greet welcome" data-bind="scope: 'customer'">
    <!-- ko if: customer().fullname  -->
    <span class="logged-in" data-bind="text: customer().fullname"></span>
    <!-- /ko -->
</div>
<script type="text/x-magento-init">
{
    "*": {
        "Magento_Ui/js/core/app": {
            "components": {
                "customer": {
                    "component": "Magento_Customer/js/view/customer"
                }
            }
        }
    }
}
</script>

Here scope is customer. Where a component is important and this must me extend uiComponent(vendor/magento/module-ui/view/base/web/js/lib/core/element/element.js).

How to create custom bindings?
1. Create app/code/VendorName/ModuleName/view/frontend/web/js/custom-binding.js

define([
    'ko',
    'Magento_Ui/js/lib/knockout/template/renderer'
], function (ko, renderer) {
    'use strict';

    ko.bindingHandlers.customBinding = {

        init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
            // This will be called when the binding is first applied to an element
            // Set up any initial state, event handlers, etc. here
            element.innerHTML = 'Custom Binding';
        },
        update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
            // This will be called once when the binding is first applied to an element,
            // and again whenever any observables/computeds that are accessed change
            // Update the DOM element based on the supplied values here.
        }
    };

    renderer
        .addNode('customBinding')
        .addAttribute('customBinding');
});

2. Now you need to register. Create app/code/VendorName/ModuleName/view/frontend/requirejs-config.js

var config = {
    config: {
        mixins: {
            'Magento_Ui/js/lib/knockout/bindings/bootstrap': {
                'VendorName_ModuleName/js/lib/knockout/bindings/bootstrap': true
            }
        }
    }
};

3. Create app/code/VendorName/ModuleName/view/frontend/web/js/lib/knockout/bindings/bootstrap.js

define(function (require) {
        'use strict';
        return function (target) {
            target.customBinding = require('VendorName_ModuleName/js/custom-binding');
            return target;
        }
    }
);

Now you can able to use this custom binding. Ex:

<div class="greet welcome" data-bind="scope: 'custom-binding-example'">
    <span data-bind="customBinding:'true'"></span>
</div>
<script type="text/x-magento-init">
{
    "*": {
        "Magento_Ui/js/core/app": {
            "components": {
                "custom-binding-example": {
                    "component": "uiComponent"
                }
            }
        }
    }
}
</script>

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.