Magento 2 – Use of Knockout.js

knockoutjsmagento-2.1magento2

I am new to Magento 2. Need help to understand the concept of the knockout.js.

Why Magento 2 has used knockout.js? I did try to understand it and did check this useful articles:

How knockout.js works

But still not getting anyhint why it has been implemented in Magento and what's the use of it?

Please help me to understand the concept of the knockout.js.

Best Answer

Magento 2 uses the Knockout.js framework to dynamically build some parts of it's frontend. It provides a great way to create interactive frontend data bound components within your Magento 2 store. Knockout.js eases working with dynamic javascript user interfaces by making use of the Model-View-ViewModel (MVVM) pattern.

Features of Knockout.js

  • Observables and dependency tracking
  • Declarative bindings
  • Templating

Observables means that you define data models in javascript that you pick for example via ajax. You than 'connect' these models with elements in a template. Does anything change in your data model than the user interface is updated automatically. This can also work the other way around. With dependency tracking we can setup chains of relationships between model and data, to transform and combine it.

With declarative binding, we can manipulate more properties of the UI instead of just showing values. Depending on our data model we can change visibility, text, html, css, styles, attributes, ...

Over at learn.knockoutjs.com they have a real nice web app set up that takes you through the basics of using Knockout.js in a 'hands-on' style. It's really fun to work through.

Knockout.js is very similar to Angularjs. But Angularjs is a very complete and large framework with dependency injection, ajax, routing, cookies and much more ... Probably Magento 2 was just looking only for a way to do data-binding.

An example of customizing the minicart

If you want to write html template structures in Magento that work with Knockout.js you have to deal with regular .html files in addition to the traditional .phtml files. These templates are loaded via ajax. You can usually find these files in app/code///view/frontend/web/template/

or in

app/design/frontend/<theme-vendor>/<theme>/<module-vendor>_<module>/web/template/. 

So they are inside the template folder inside the web folder and not in the regular templates folder.

To modify the minicart we must copy the file app/code/Magento/Checkout/view/frontend/web/template/minicart/content.html to our theme folder. So we copy the file to app/design/frontend/<your-theme-vendor>/<your-theme>/Magento_Checkout/web/template/minicart/content.html

Inside this template file we can use al sorts of code structures like an 'if' structure for example. Say we want to hide elements when the cart is empty, we can add the following around a code block.

<!-- ko if: cart().summary_count == 0 -->
    <div>some code</div>
<!-- /ko -->

Using the syntax with comments like this is called 'containerless control flow syntax'. We could also bind this to the container itself of course. Like so:

<div data-bind="if: cart().summary_count == 0">some code</div>

Similar to the if binding there is also the foreach binding.

<!-- ko foreach: someArray --><!-- /ko -->

We can also add text that can be translated.

<span class="notice"><!-- ko i18n: 'All prices are tax included.' --><!-- /ko --></span>

Calling another template can be done with the template binding.

<!-- ko template: 'path/to/template' --><!-- /ko -->

The part that initially loads the content form the minicart in the header comes from a regular .phtml file, that can be found app/code/Magento/Checkout/view/frontend/templates/cart/minicart.phtml Here we also see some knockout.js bindings.

For instance we can change the code that shows the counter next to the cart icon from:

<!-- ko if: cart().summary_count -->
    <!-- ko text: cart().summary_count --><!-- /ko -->
    <!-- ko i18n: 'items' --><!-- /ko -->
<!-- /ko -->

to:

<!-- ko if: cart().summary_count == 1 -->
    <!-- ko i18n: 'item' --><!-- /ko -->
<!-- /ko -->
<!-- ko if: cart().summary_count != 1 -->
    <!-- ko i18n: 'items' --><!-- /ko -->
<!-- /ko -->

Now the counter also shows up when there are actually zero items in the cart. And it shows '0 items'.

Source: studioemma

Related Topic