KnockoutJs custom bindings in Magento 2

Today I will discuss KnockoutJs two important custom bindings in Magento 2. This is the series of Magento 2 Certified Professional Javascript Developer exam.

Two important knockoutjs bindings are:

1. Knockout Fast Foreach
2. Repeat

How these bindings are the map in magento 2?
vendor/magento/module-ui/view/base/web/js/lib/knockout/bindings/bootstrap.js

1. Knockout Fast Foreach
KnockoutJs default foreach is slow for large data. For overcome this slowness magento use Knockout Fast Foreach out of box. Location lib/web/knockoutjs/knockout-fast-foreach.js. Ex.

<div data-bind="scope: 'outerfasteach-example'">
    <table>
        <thead>
            <tr><th>First name</th><th>Last name</th></tr>
        </thead>
        <tbody data-bind='fastForEach: {data: getCustomerData()}'>
            <tr>
                <td data-bind="text: firstName"></td>
                <td data-bind="text: lastName"></td>
            </tr>
        </tbody>
    </table>
</div>
<script type="text/x-magento-init">
{
    "*": {
        "Magento_Ui/js/core/app": {
            "components": {
                "outerfasteach-example": {
                    "component": "VendorName_ModuleName/js/fast-foreach"
                }
            }
        }
    }
}
</script>

app/code/VendorName/ModuleName/view/frontend/web/js/fast-foreach.js

define([
    'ko',
    'uiComponent',
    'underscore'
], function (ko, Component, _) {
    'use strict';

    return Component.extend({
        customerNameList: ko.observableArray([]),
        /** @inheritdoc */
        initialize: function () {
            this._super();
            var self = this;
            for (var i = 0; i < 5000; i++) {
                self.customerNameList.push({'firstName': 'firstName_'+i, 'lastName': 'lastName_'+i});
            }
        },
        getCustomerData: function () {
            return this.customerNameList;
        }
    });
});

You can use as a node, so attribute name should be outerfasteach. Check here how magento uses in the grid listing:
vendor/magento/module-ui/view/base/web/templates/grid/listing.html

<div class="admin__data-grid-wrap" data-role="grid-wrapper">
    <table class="data-grid" data-role="grid">
       <thead>
            <tr each="data: getVisible(), as: '$col'" render="getHeader()"/>
        </thead>
        <tbody>
            <tr class="data-row" repeat="foreach: rows, item: '$row'" css="'_odd-row': $index % 2">
                <td outerfasteach="data: getVisible(), as: '$col'"
                    css="getFieldClass($row())" click="getFieldHandler($row())" template="getBody()"/>
            </tr>
            <tr ifnot="hasData()" class="data-grid-tr-no-data">
                <td attr="colspan: countVisible()" translate="'We couldn\'t find any records.'"/>
            </tr>
        </tbody>
    </table>
</div>

2. Repeat

You can use repeat binding alternative of foreach. This is also faster than foreach binding.

Here’s a comparison between foreach and repeat for a data table:

<table>
    <tbody data-bind="foreach: data">
        <tr data-bind="foreach: $parent.columns">
            <td data-bind="text: $parent[$data.propertyName]"></td>
        </tr>
    </tbody>
</table>

<table>
    <tbody>
        <tr data-bind="repeat: { foreach: data, item: '$row' }">
            <td data-bind="repeat: { foreach: columns, item: '$col' }"
                data-repeat-bind="text: $row()[$col().propertyName]"></td>
        </tr>
    </tbody>
</table>

For more details, you can check here

Magento uses this in timeline:
vendor/magento/module-ui/view/base/web/templates/timeline/timeline.html

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.