1

So, i'm very new when it comes to using KnockoutJS but i've been doing some reading around it and to my knowledge each template file has its own corresponding model.

However, as i'm looking through the template file located at:

module-checkout/view/frontend/web/template/minicart/item/default.html

I cannot find any reference to the model it is linked to. My goal is to add an afterAdd function to the foreach contained within the following code block:

<!-- ko foreach: { data: options, as: 'option' } -->
<dt class="label"><!-- ko text: option.label --><!-- /ko --></dt>
<dd class="values">
    <!-- ko if: Array.isArray(option.value) -->
        <span data-bind="html: option.value.join('<br>')"></span>
    <!-- /ko -->
    <!-- ko ifnot: Array.isArray(option.value) -->
        <span data-bind="html: option.value"></span>
    <!-- /ko -->
</dd>
<!-- /ko -->

This should then call the corresponding afterAdd function within the model and I can run some code. But after looking through the models located within:

module-checkout/view/frontend/web/js/model

i'm having no luck finding it.

Update:

It is possible that I have found the corresponding file under:

module-checkout/view/frontend/web/js/view/minicart.js

However, adding a callback function so that I can run some code in this file is still an issue.

1 Answer 1

6

Open

vendor/magento/module-checkout/view/frontend/layout/default.xml

Now you can able to see how the minicart renders and how it binds with knockoutjs. Check the following code snippet.

<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>
</item>

This is your template:

Magento_Checkout/minicart/content

Corresponding js

Magento_Checkout/js/view/minicart

Now open

vendor/magento/module-checkout/view/frontend/web/template/minicart/content.html

Check the following code snippet on how to render the item

<if args="getCartParam('summary_count')">
    <strong class="subtitle" translate="'Recently added item(s)'"/>
    <div data-action="scroll" class="minicart-items-wrapper">
        <ol id="mini-cart" class="minicart-items" data-bind="foreach: { data: getCartItems(), as: 'item' }">
            <each args="$parent.getRegion($parent.getItemRenderer(item.product_type))"
                  render="{name: getTemplate(), data: item, afterRender: function() {$parents[1].initSidebar()}}"
            />
        </ol>
    </div>
</if>

$parent.getItemRenderer(item.product_type) this is actually retrun defaultRenderer from the Magento_Checkout/js/view/minicart class.

How?

Open vendor/magento/module-checkout/view/frontend/layout/checkout_cart_sidebar_item_renderers.xml

Here, define the item template and render.

<item name="config" xsi:type="array">
    <item name="itemRenderer" xsi:type="array">
        <item name="default" xsi:type="string">defaultRenderer</item>
        <item name="simple" xsi:type="string">defaultRenderer</item>
        <item name="virtual" xsi:type="string">defaultRenderer</item>
    </item>
</item>

So $parent.getRegion($parent.getItemRenderer(item.product_type)) now looks like:

$parent.getRegion(defaultRenderer)

If you check vendor/magento/module-checkout/view/frontend/layout/checkout_cart_sidebar_item_renderers.xml

<item name="children" xsi:type="array">
    <item name="item.renderer" xsi:type="array">
        <item name="component" xsi:type="string">uiComponent</item>
        <item name="config" xsi:type="array">
            <item name="displayArea" xsi:type="string">defaultRenderer</item>
            <item name="template" xsi:type="string">Magento_Checkout/minicart/item/default</item>
        </item>
        <item name="children" xsi:type="array">
            <item name="item.image" xsi:type="array">
                <item name="component" xsi:type="string">Magento_Catalog/js/view/image</item>
                <item name="config" xsi:type="array">
                    <item name="template" xsi:type="string">Magento_Catalog/product/image</item>
                    <item name="displayArea" xsi:type="string">itemImage</item>
                </item>
            </item>
        </item>
    </item>
</item>

Check this line

<item name="displayArea" xsi:type="string">defaultRenderer</item>

Product item comes vendor/magento/module-checkout/CustomerData/DefaultItem.php

Inside vendor/magento/module-checkout/view/frontend/web/template/minicart/item/default.html you can access all.

If you want to add js, then overwrite Magento_Checkout/js/view/minicart and added here. You can access that method using $parent from template.

5
  • Brilliant answer and well explained! Thanks for the help Sohel - A Commented Apr 12, 2019 at 8:07
  • Alright so I have been playing around with this a little bit but I cant seem to get the callback function to work correctly. I have changed ko foreach: { data: options, as: 'option' } to ko foreach: { data: options, as: 'option', afterRender: updateBundle }. Where abouts in the minicart.js file do I place this callback function as it keeps saying its undefined Commented Apr 12, 2019 at 11:10
  • 1
    Use $parents[1]. updateBundle, something like that.
    – Sohel Rana
    Commented Apr 12, 2019 at 11:13
  • You're a star. Up and working now as expected! It took a while to get my head around it but you've helped a lot. Cheers - A Commented Apr 12, 2019 at 11:34
  • Great. Happy to help :)
    – Sohel Rana
    Commented Apr 12, 2019 at 11:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.