Magento 2 is heavily using Knockout Js on frontend. You can find  Knockout in Magento 2 on almost every page.
For example in : on minicart vendor\magento\module-checkout\view\frontend\templates\cart\minicart.phtml

<div id="minicart-content-wrapper" data-bind="scope: 'minicart_content'">
    <!-- ko template: getTemplate() --><!-- /ko -->

To understand how it works, I created a simple module Magento 2 Knockout Js Simple Module  to explain it.
You can download it and check te result of this tutorial on github. :




This module allows us to add/remove seat reservation and calculate total charge dynamically using Knockout JS.
You can follow my instruction on github Readme file for installing this module.
Access it via http://your_locahost/knockout/index/view


1/ Introduce Knockout Js.

Knockout is a JavaScript library that helps you to create rich, responsive display and editor user interfaces with a clean underlying data model. It implements Model-View-View Model (MVVM) design pattern.
If you’re not familiar with Knockout Js. You can look at : Knockout site .

So, in quick conclusion, KO provides a client side JS abstraction that enhances your stock JavaScript library in the following ways:

1. Greatly simplifies synchronization between the client UI and server.
2. Leverages MVVM design pattern to increase modularity and provide for a clean separation of concerns and cohesive implementations.
3. Keeps UI model state management on the client (where it belongs).
4. Decreases (potentially) the size of server responses and client/server traffic in general (thereby speeding up our apps).


2/ How Knockout Js simple module works:

2.1/ My simple module create a new route : knockout/index/view to load a custom template  Grid.phtml: 

In file :   app\code\Thienphucvx\Knockout\view\frontend\layout\knockout_index_view.xml

<block class="Thienphucvx\Knockout\Block\ViewAbstract" before="-" cacheable="false" template="Thienphucvx_Knockout::grid.phtml">

Here is the  content of Grid.phtml:

<div id="block-sample-grid" data-bind="scope:'sample-grid'" class="block">

    <!-- ko template: getTemplate() --><!-- /ko -->

    <script type="text/x-magento-init">


        "#block-sample-grid": {

            "Magento_Ui/js/core/app": <?php /* @escapeNotVerified */ echo $block->getJsLayout();?>





2.2/ In grid.phtml, it will load js\view\grid.js file based on  knockout_index_view.xml and get right template based on grid.js configuration.
As you can see we set “data-bind=”scope:’sample-grid’“.  The row “$block->getJsLayout()” => will read configuration from knockout_index_view.xml

Based on this configuration “<item name=”component” xsi:type=”string”>Thienphucvx_Knockout/js/view/grid</item>“, it will render like this :
“Magento_Ui/js/core/app”: {“components”:{“sample-grid”:{“component”:”Thienphucvx_Knockout\/js\/view\/grid”}}}
It will load “app\code\Thienphucvx\Knockout\view\frontend\web\js\view\grid.js” for component : “sample-grid“.

In “view\frontend\web\js\view\grid.js”: We set default template via this line code
“defaults: {
template: ‘Thienphucvx_Knockout/grid’},”
It means we tell magento 2 that virtual element “<!– ko template: getTemplate() –><!– /ko –>” to load “view\frontend\web\template\grid.html” for displaying content of scope component “sample-grid“.

Summary explain how Knockout Js Module Works

Explain how Knockout Js Module Works
Finally grid.html will be loaded :

<h2>Your seat reservations (<span data-bind="text: seats().length"></span>)</h2>

        <th>Passenger name</th><th>Meal</th><th>Surcharge</th><th></th>
    <tbody data-bind="foreach: seats">
        <td><input data-bind="value: name" /></td>
        <td><select data-bind="options: $parent.availableMeals, value: meal, optionsText: 'mealName'"></select></td>
        <td data-bind="text: formattedPrice"></td>
        <td><a href="#" data-bind="click: function(data,event){$parent.removeSeat($parent,data);}">Remove</a></td>


<button data-bind="click:addSeat, enable: seats().length < 5">Reserve another seat</button>

<h3 data-bind="visible: totalSurcharge() > 0">
    Total surcharge: $<span data-bind="text: totalSurcharge().toFixed(2)"></span>

I believe from that point, you can dig into grid.html to understand how my module works. If you have trouble on understand what is “$parent”, you can read it at here :

Magento 2 use “scope” to binding View-model instead of applying via “ko.applyBindings(new AppViewModel())” as normal Knockout. You can read Alan article to know more about it


Some more resources about Knockout JS on Magento2: