Magento2 manage dynamic JavaScript UIs with the Model-View-View Model (MVVM) pattern
“knockoutjs” , yes observe and change data with easy and structured way (HTML data bindings). In this tutorial will be introduce "Virtual elements" <!-- ko --> <!-- /ko -->.
knockoutjs work with two type of element Normal node and Comment node '"Virtual elements" is an abstraction on top of the usual DOM API which understands the notion that comment nodes' , The point of all this is to support containerless templates (e.g., <!-- ko foreach:someCollection -->blah<!-- /ko -->)
if you play inside .phtml files you will finding <!-- ko --> anywhere , but in this tutorial we want analyze <!-- ko template: getTemplate() --> .
Firstly :
you can see this tutorial about Knockout Container less Templates in youtube is very helpful.
Small global example :
after included knockout.js inside your any html head tag put:
<div class='topclass' data-bind="template: 'subTmpl'"></div> <script id="subTmpl" type="text/html"> <div class="myclass" data-bind="text: 'SomeText'"></div> </script>
simple here I tell to knockout fill my element with template where id is 'subTmpl' here simple result my element (imagine render not the code source) it will be filled as :
<div class='topclass'> <div class="myclass" >SomeText</div> </div>
Frontend Case :
1 – declare template inside layout
Open vendor/magento/module-checkout/view/frontend/templates/cart/minicart.phtml ,you will finding:
<div id="minicart-content-wrapper" data-bind="scope: 'minicart_content'"> <!-- ko template: getTemplate() --><!-- /ko --> </div>
If you go to layout responsible "handler" of this block vendor/magento/module-checkout/view/frontend/layout/default.xml in top you will find :
….......................... <block class="Magento\Checkout\Block\Cart\Sidebar" name="minicart" as="minicart" after="logo" template="cart/minicart.phtml"> <arguments> <argument name="jsLayout" xsi:type="array"> <item name="types" xsi:type="array"/> <item name="components" xsi:type="array"> <item name="minicart_content" xsi:type="array"> <item name="component" xsi:type="string">Magento_Checkout/js/view/minicart</item> <item name="config" xsi:type="array"> <item name="template" xsi:type="string">Magento_Checkout/minicart/content</item> …..................................
Note : here the team Magento2 declare the js responsible of this component and template inside the layout .xml you can See: Magento_Checkout/js/view/minicart equal vendor/magento/module-checkout/view/frontend/web/js/view/minicart.js and Magento_Checkout/minicart/content equal vendor/magento/module-checkout/view/frontend/web/template/minicart/content.html but you can add the template inside the js responsible of component.
if you go to vendor/magento/module-checkout/view/frontend/cart/minicart.phtm you can see:
<script type="text/x-magento-init"> { "[data-block='minicart']": { "Magento_Ui/js/core/app": <?php /* @escapeNotVerified */ echo $block->getJsLayout();?> }, "*": { "Magento_Ui/js/block-loader": "<?php /* @escapeNotVerified */ echo $block->getViewFileUrl('images/loader-1.gif'); ?>" } } </script>
the declaration of component is "Magento_Ui/js/core/app": <?php /* @escapeNotVerified */ echo $block->getJsLayout();?> ,Yes we get the content from the xml and from the block Magento\Checkout\Block\Cart\Sidebar magento use $block->getJsLayout() for convert to format json.
Ok how Magento 2 Ui use Knockoutjs and other intern js for getting the final result. Normally the standard Knockoutjs included from magento2/lib/web/knockoutjs and the other part created by magento2 team for personalized the native tasks and add other tasks is inside vendor/magento/module-ui/view/base/web/js/lib/ko , Ok Ko read the virtual element <!-- ko template: getTemplate() --><!-- /ko --> globally ko process and take the directive template (we want bind data in this element by using a predefine template) , this process is done inside Knockoutjs.js from line 2555 to 2625 finally you get : return new Function("$context", "$element", functionBody);
but where is the getTemplate() function wow it's inside : magento2/app/code/Magento/Ui/view/base/web/js/lib/core/element/element.js
getTemplate: function () { return this.template; },
you can use for example console.log(this.template); and you see all templates used inside many .phtml with virtual element:
"Magento_Checkout/minicart/content" element.js:256
"Magento_Checkout/minicart/subtotal" element.js:256
"Magento_Checkout/minicart/item/default" element.js:256
"Magento_Tax/checkout/minicart/subtotal/totals" element.js:256
you can add the component and with it you can create you own js related to this template and put the template.
2 – declare template inside js:
You can declare the template inside .xml layout with the component declaration or inside the js related component go to:
Magento/Customer/view/frontend/templates/account/authentication-popup.phtml you will find in the line 13:
<!-- ko template: getTemplate() --><!-- /ko -->
and inside vendor/magento/module-customer/view/frontend/layout/default.xml you have:
…................. <block class="Magento\Customer\Block\Account\AuthenticationPopup" name="authentication-popup" as="authentication-popup" template="account/authentication-popup.phtml"> <arguments> <argument name="jsLayout" xsi:type="array"> <item name="components" xsi:type="array"> <item name="authenticationPopup" xsi:type="array"> <item name="component" xsi:type="string">Magento_Customer/js/view/authentication-popup</item>
Magento_Customer/js/view/authentication-popup is a .js inside :
vendor/magento/module-customer/view/frontend/web/js/view and it have the path of template:
return Component.extend({ registerUrl: window.authenticationPopup.customerRegisterUrl, forgotPasswordUrl: window.authenticationPopup.customerForgotPasswordUrl, modalWindow: null, isLoading: ko.observable(false), defaults: { template: 'Magento_Customer/authentication-popup' },
The path of template Magento_Customer/authentication-popup is inside vendor/magento/module-customer/view/frontend/web/template/authentication-popup.html
Comments