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
Best Answer
Create the view part of the checkout step component To create the view part of the new checkout step:
Add a module directory (not covered in this topic). See Build your module for details). All custom files must be stored there. For your checkout customization to be applied correctly, your custom module should depend on the Magento_Checkout module. Do not use Ui for your custom module name, because %Vendor%_Ui notation, required when specifying paths, might cause issues. Create the .js file implementing the view model. Create an .html template for the component. Each step is described.
Add the JavaScript file implementing the new step A new checkout step must be implemented as UI component. That is, its JavaScript implementation must be a JavaScript module. The file must be stored under the /view/frontend/web/js/view directory. notation stands for the path to your module directory from the root directory. Usually it will be one of the following: app/code// or vendor//module--. For more details see Conventional notations for paths to modules and themes A sample my-step-view.js with comments follows:
Add the .html template In the module directory, add the .html template for the component. It must be located under the /view/frontend/web/template directory.
A sample mystep.html follows:
Add your step to the Checkout page layout For the new step to be displayed on the page, you need to declare it in the Checkout page layout, which is defined in checkout_index_index.xml.
So you need to add an extending checkout_index_index.xml layout file in the following location: /view/frontend/layout/checkout_index_index.xml
A sample checkout_index_index.xml follows:
%Vendor%_%Module%/js/view/my-step-view 2 --> 2