Get Free Audit

What is Knockout JS Framework in Magento 2?

Mar 28, 2019

7400 Andrey Litvin

What is Knockout JS Framework in Magento 2?

Knockout.js — is a library that allows you to create dynamic interfaces and use different bindings for DOM elements. It implements the Model-View-ViewModel pattern and is used in Magento 2 dynamic modules such as Checkout, Customer, etc. In this article I will refer to module files that use knockout.js, and also describe how to use the framework to perform various functions in Magento 2.

Table of contents:

How do you use knockout.js bindings
How do you bind a ko view model to a section of the DOM with the scope binding
How do you render a ko template of a UiComponent
Demonstrate an understanding of the different types of knockout observables
What common ko bindings are used
Demonstrate an understanding of ko virtual elements

Before I will explore each question in greater detail, it is necessary to explain the Model-View-ViewModel. MVVC consists of 3 components:

  • Model contains data
  • View reflects the data on the screen
  • ViewModel is an intermediary between Model and View, allows to obtain data for View and influence Model

With that knowledge in mind, we can proceed to the main part of the article.

How do you use knockout.js bindings

Binding is the ability to bind various components to HTML. In knockout.js, the html attribute data-bind is used for this. Here is how the binding is implemented, using the user greeting component on the frontend of Magento 2 as the example:

https://github.com/magento/magento2/blob/2.2/app/code/Magento/Customer/view/frontend/templates/account/customer.phtml


If we assume that the value of fullname is observable, then as soon as the value of fullname changes, this value changes correspondingly on the website.

There are many different bindings, and all of them are described in the knockout.js documentation (https://knockoutjs.com/documentation/introduction.html). Here are some of them: visible, text, html, if, foreach, click.

Also, Magento 2 has its own custom bindings, and all of them can be specified in the data-bind attribute, while some of them can be specified as an attribute, a virtual element knockout.js or as a custom element. Here are some of them:


  1. It is responsible for the output of the template specified in the component, here is the function responsible for this output:
    https://github.com/magento/magento2/blob/2.2/app/code/Magento/Ui/view/base/web/js/lib/core/element/element.js#L266

  2. This is a virtual element used for translation in Magento 2. You might want to use <! – ko text: ->, yet bear in mind that the code I suggest was created with the aim that everything would integrate with the translations in Magento 2. You can also use data-bind as an attribute:

  3. This one is used to add a function after the item is rendered.

  4. This binding is used to fade in or fade out of the element depending on the function result.

  5. This binding is used to initiate jqueryUi widget.

Here is the list of knockout bindings:

1.Layout:

  • visible – show / hide an element depending on the condition
  • text – displays text, html tags will be displayed as text
  • html – displays html, html tags will be rendered
  • css – add css class depending on the condition
  • style – add css style depending on the condition
  • attr – set attribute values

2. Flow:

  • foreach – duplicates the element content for each item in the specified array
  • if – adds the contents of the condition block to the DOM if it is true
  • ifnot – adds the contents of the condition block to the DOM if it is false
  • with – creates a new bundling property context in which you can refer directly to the sub-properties of this property.
  • component – embeds an external component in the DOM

3. Fields:

  • click – function is called when clicked on
  • event – function is called when an event occurs
  • submit – function is called upon submit
  • enable – turns on the element when the condition is true
  • disable – disables the element when the condition is true
  • value – changes the value of the form field
  • textInput – similar to value, works only with text fields, provides for all types of user input, including autocomplete, drag-and-drop, and clipboard events
  • hasFocus – changes the value of the property when is received (to true) and the focus is lost (to false)
  • checked – changes property value when selecting checkbox and radio elements
  • options – provides options for dropdown
  • selectedOptions – provides selected options from the dropdown
  • uniqueName – sets a unique name for form fields with an empty name

4. Template rendering:

  • template – renders another template

How do you bind a ko view model to a section of the DOM with the scope binding

Connects the Ui element with the component that is declared in xml in jsLayout or in <script type=”text/x-magento-init”>, and the already registered one in uiRegistry.

I will cite the checkout as an example.

xml:


In the line <item name=”checkout” xsi:type=”array”> in the attribute name we declare the component name, checkout in our case, and call it in phtml:


In this example we immediately created checkout in xml, and then it was binded to UiRegistry with the help of our configurations parcing specified in xml and getting them with the help of json with с помощью парсинга наших настроек указанных xml и получением их с помощью json with $block->getJsLayout() php function.


Also, if we bind a component to a DOM element through data-mage-init, the scope is bound to the element to which we have bound the component or widget.

Example:


The #checkout-loader element becomes the scope of the checkoutLoader component.

How do you render a ko template of a UiComponent

Knockout templates can be specified in different ways, and I will try to cover possible ways to specify templates for UiComponent.

Method #1. Specify the component in the viewmodel file itself, for example, as is done in the pop-up authorization form:

https://github.com/m1kash/magento2/blob/2.2-develop/app/code/Magento/Customer/view/frontend/web/js/view/authentication-popup.js#L28

Code:


As you can see, the standard template Magento_Customer / authentication-popup will be used, and when we create our custom component ui, we can specify our template via mixin, layout, text / x-magento-init, data-mage-init.

Method #2. Specify our template in text / x-magento-init:


Method #3. Specify in jsLayout, the way it was done in checkout:


For the Magento_Checkout / js / view / summary component, apply the template that we specified in xml: Magento_Checkout / summary.

Method #4. Specify the template directly in the template where our component is called the following way:


For the first 3 ways, we need to specify a call to our template, as it is done in checkout:
https://github.com/magento/magento2/blob/2.2/app/code/Magento/Checkout/view/frontend/templates/onepage.phtml#L17.


As you can see from the code, we declared the scope for the #checkout element and called the function getTemplate () via the virtual element. To learn how the function performs follow the link (https://github.com/magento/magento2/blob/2.2/app /code/Magento/Ui/view/base/web/js/lib/core/element/element.js#L266)
but in simple words it receives a link to the static address of our template and after all this it renders our template.
Here is the example of the github component’s checkout template (https://github.com/magento/magento2/blob/2.2/app/code/Magento/Checkout/view/frontend/web/template/onepage.html):


It is clear from the heatworm that we use foreach, alternately displaying data from an array or $ date object, for example, in the last foreach, getRegion () is used to get the sidebar and so on. The function code is in github(https://github.com/m1kash/magento2/blob/2.2-develop/app/code/Magento/Ui/view/base/web/js/lib/core/collection.js#L205).

Igor Dragun

Partner With Us

Let's discuss how to grow your business. Get a Free Quote.
Talk to Igor

Demonstrate an understanding of the different types of knockout observables

Observables are the observable objects and arrays that are updated asynchronously as the value changes. In knockout.js, this is implemented by the following functions:

1. ko.observable() – the function is used for observable objects to change values asynchronously, for example, when receiving data from json.
2. ko.observableArray([]) – the function is used for the observed arrays, which can also be updated asynchronously. You can also change the values and use methods for arrays such as: .map, .filter, .each, etc.

If we want to assign a value to the observed object or array, then we pass our value to the function argument:


understanding knockout framework

If we want to get a value from an observable object or array, then we call our function with no arguments:


nderstanding knockout framework name

1. To get the value before assignment, you need to write the following structure:


2. To get the value after assignment, you need to write the following structure:


Then there are also calculable functions:

1. ko.computed(callback) —used to update the value when changing which observable object is used in this function.
2. ko.pureComputed(callback) — used to return observable objects but without update. Due to this, the performance is improved and less memory is needed than with the ko.computed function.

Example of the Observables function.

html:

The name is


script:


Output before pressing the Change button:
“The name is Bob.”

Output after pressing the Change button:
“The name is Alice.”

What common ko bindings are used

It was already mentioned that you can find most of the bindings in the knockout.js documentation (https://knockoutjs.com/documentation/introduction.html). Let’s consider the main ones used in Magento:


  1. It is clear from the name that this one is responsible for the visibility of the element and takes the value of boolean.

  2. This binding is used to display text.

  3. This binding is used for html output.

  4. attr binding is used for attributes output.

  5. The binding is used to bind the function to the event when the element is clicked; if the function is callback, then we indicate only the name without calling.

    These were the bindings most commonly used in Magento, and as I have already mentioned, the rest can be found on the official website knockout.js in the documentation.

Demonstrate an understanding of ko virtual elements

Virtual elements are a child element binding without the need to insert html to bind an element. Virtual elements are used to render the html document. Here is the example of how it is done in the template of payment methods (https://github.com/m1kash/magento2/blob/2.2-develop/app/code/Magento/Checkout/view/frontend/web/template/payment.html):


These are the most common virtual elements used in Magento 2:


  1. used to iterate over arrays to display date from an array.

  2. used to output data from an array according to the template that we will specify in the template.

  3. used to check the condition of data display from the condition; there is also

    this one is used for opposite conditions.

  4. used for translation in Magento 2.

  5. used for text output from functions, observed objects, etc.

What are the pros and cons of knockout templates

Knockout templates have the following advantages:

  1. Support for older browsers up to IE 6;
  2. Simple library;
  3. Separating HTML and JavaScript;
  4. Dynamic data binding.

However, knockout templates have certain disadvantages:

  1. Poor performance if many objects;
  2. Magento switches to PWA, uses React, and Knockout will sooner or later become deprecated.

FAQ: Compare knockout templates with underscore JavaScript templates

  1. Underscore template is rendered only when the method _.template (template) (params) is called, while Knockout template is automatically re-rendered if data changes.
  2. Underscore uses <% = …%>, <% …%>, <% – …%> blocks to execute scripts. Knockout uses the data-bind attribute in html elements and html comments.

Wrapping it up

This was the article about the knockout framework and how to work with it in Magento 2. If you have any questions or comments, feel free to leave them down below.

Igor Dragun
Partner With Us Looking for a partner to grow your business? We are the right company to bring your webstore to success. Talk to Igor

1 comment

Post a new comment

BelVG Newsletter
Subscribe to our mailing list and get interesting stuff and updates to your email inbox.
Email *