Unfortunately I can't paste the content (it's too extensive anyway) so I can just give a link.
I found Alan Storm has written a series where he explains the Javascript concepts of Magento 2.
If you read this answer you will hopefully still find it here:
http://alanstorm.com/category/magento-2/#magento2-advanced-javascript
With the information from above I try to analyze what happens (feel free to add any information to clarify things or correct me):
Actually the code in the question is not enough to analyze it. Let's look at the whole code.
<?php
/**
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
// @codingStandardsIgnoreFile
/** @var $block \Magento\Checkout\Block\Cart\Sidebar */
?>
<div data-block="minicart" class="minicart-wrapper">
<a class="action showcart" href="<?php /* @escapeNotVerified */ echo $block->getShoppingCartUrl(); ?>"
data-bind="scope: 'minicart_content'">
<span class="text"><?php /* @escapeNotVerified */ echo __('My Cart'); ?></span>
<span class="counter qty empty"
data-bind="css: { empty: !!getCartParam('summary_count') == false }, blockLoader: isLoading">
<span class="counter-number"><!-- ko text: getCartParam('summary_count') --><!-- /ko --></span>
<span class="counter-label">
<!-- ko if: getCartParam('summary_count') -->
<!-- ko text: getCartParam('summary_count') --><!-- /ko -->
<!-- ko i18n: 'items' --><!-- /ko -->
<!-- /ko -->
</span>
</span>
</a>
<?php if ($block->getIsNeedToDisplaySideBar()): ?>
<div class="block block-minicart empty"
data-role="dropdownDialog"
data-mage-init='{"dropdownDialog":{
"appendTo":"[data-block=minicart]",
"triggerTarget":".showcart",
"timeout": "2000",
"closeOnMouseLeave": false,
"closeOnEscape": true,
"triggerClass":"active",
"parentClass":"active",
"buttons":[]}}'>
<div id="minicart-content-wrapper" data-bind="scope: 'minicart_content'">
<!-- ko template: getTemplate() --><!-- /ko -->
</div>
<?php echo $block->getChildHtml('minicart.addons'); ?>
</div>
<?php endif ?>
<script>
window.checkout = <?php /* @escapeNotVerified */ echo \Zend_Json::encode($block->getConfig()); ?>;
</script>
<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>
</div>
You need to go further up the code sample than what I initially posted. The first thing to find is: <a class="action showcart" ... data-bind="scope: 'minicart_content'"
.
What Magento does here is (I'll quote Alan's series):
Magento will apply the [minicart_content] view model to this tag and its descendants.
But where does the minicart_content
view model come in place? You have to look a bit further down in the code at the x-magento-init
script tag:
<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>
Here Magento sets, via knockoutJs, the loaderAnimation.gif. And before the minicart is somehow initialized to the data-block
named minicart
by [data-block='minicart']
which suspiciously looks like a CSS style selector.
For me what is returned by $block->getJsLayout()
is the following:
{
"components":{
"minicart_content":{
"children":{
"subtotal.container":{
"children":{
"subtotal":{
"children":{
"subtotal.totals":{
"config":{
"display_cart_subtotal_incl_tax":0,
"display_cart_subtotal_excl_tax":1,
"template":"Magento_Tax\/checkout\/minicart\/subtotal\/totals"
},
"children":{
"subtotal.totals.msrp":{
"component":"Magento_Msrp\/js\/view\/checkout\/minicart\/subtotal\/totals",
"config":{
"displayArea":"minicart-subtotal-hidden",
"template":"Magento_Msrp\/checkout\/minicart\/subtotal\/totals"
}
}
},
"component":"Magento_Tax\/js\/view\/checkout\/minicart\/subtotal\/totals"
}
},
"component":"uiComponent",
"config":{
"template":"Magento_Checkout\/minicart\/subtotal"
}
}
},
"component":"uiComponent",
"config":{
"displayArea":"subtotalContainer"
}
},
"item.renderer":{
"component":"uiComponent",
"config":{
"displayArea":"defaultRenderer",
"template":"Magento_Checkout\/minicart\/item\/default"
},
"children":{
"item.image":{
"component":"Magento_Catalog\/js\/view\/image",
"config":{
"template":"Magento_Catalog\/product\/image",
"displayArea":"itemImage"
}
},
"checkout.cart.item.price.sidebar":{
"component":"uiComponent",
"config":{
"template":"Magento_Checkout\/minicart\/item\/price",
"displayArea":"priceSidebar"
}
}
}
},
"extra_info":{
"component":"uiComponent",
"config":{
"displayArea":"extraInfo"
}
},
"promotion":{
"component":"uiComponent",
"config":{
"displayArea":"promotion"
}
}
},
"config":{
"itemRenderer":{
"default":"defaultRenderer",
"simple":"defaultRenderer",
"virtual":"defaultRenderer"
},
"template":"Magento_Checkout\/minicart\/content"
},
"component":"Magento_Checkout\/js\/view\/minicart"
}
},
"types":[
]
}
Now that's a whole lot of hoopla!
For our purpose here we will find where the minicart_content
view model comes from. I'll quote Alan again:
As we know [...] when Magento encounters a text/x-magento-init script tag with an * attribute, it will
- Initialize the specified RequireJS module (Magento_Ui/js/core/app)
- Call the function returned by that module, passing in the data object
The Magento_Ui/js/core/app RequireJS module is a module that instantiates KnockoutJS view models to use with the scope attribute. Its full implementation is beyond the, um, “scope” of this article, but at a high level Magento will instantiate a new javascript object for each individual RequireJS module configured as a component, and that new object becomes the view model.
Now we can see that a whole lot of components are initialized here like for the product images in the cart. But also this one: "component":"Magento_Checkout\/js\/view\/minicart"
.
This translates to the file module-checkout/view/frontend/web/js/view/minicart.js
that @Mitch7663 pointed at in his answer.
Here you find the function getCartParam
that's referenced in the template file:
<span class="counter-number"><!-- ko text: getCartParam('summary_count') --><!-- /ko --></span>
With the use of knockoutJs magic this places a text node with the return of getCartParam
called with the identifier summary_count
. Which itself is the key of a field in this.cart
.
This is as far as I got now. I'm not yet sure where the data from this.cart
gets into all of this. Also I skipped all the hazzle with observables and what not that you can read about in Alans series...no actually you should read it!
Also it seems like Magento breaks its own standards here as I see stuff selected with jQuery in that file when actually that should come from outside of it.
Anyway I'll update the answer if I get further.
Best Answer
Hey Bhupendra here answer for you,
You will need to override the template file for summery block using requirejs-config.js(create this file in your module`s view/frontend/requirejs-config.js)
up vote if you are satisfied with answer. :)