Magento – Magento 2 knockout component scope

knockoutjsmagento-2.1uicomponent

I have two knockout components. The xml in layout is:

<body>
    <referenceContainer name="content">
        <block class="Vendor\Module\Block\List" name="some_name" template="list.phtml">
        <arguments>
            <argument name="jsLayout" xsi:type="array">
                <item name="components" xsi:type="array">
                    <item name="js_list" xsi:type="array">
                        <item name="component" xsi:type="string">Vendor_Module/js/js-list</item>
                        <item name="config" xsi:type="array">
                            <item name="template" xsi:type="string">Vendor_Module/js-list</item>
                        </item>
                        <item name="children" xsi:type="array">
                            <item name="js_item" xsi:type="array">
                                <item name="component" xsi:type="string">Vendor_Module/js/js-item</item>
                                <item name="config" xsi:type="array">
                                    <item name="template" xsi:type="string">Vendor_Module/js-item</item>
                                </item>
                            </item>
                        </item>
                    </item>
                </item>
            </argument>
        </arguments>
        </block>
    </referenceContainer>
</body>

The component js_list has a template that contains the fallowing:

<div data-bind="foreach: someArray, visible: someArray().length > 0 ">
    <p data-bind="scope: 'js_list.js_item'">
        <!-- ko template: getTemplate() --><!-- /ko -->
        <p data-bind="text: testVarThatPrintsTest"></p>
    </p>
</div>

The content of the template from the component js_item is printed out but when I try to access the variable defined in it testVarThatPrintsTest :

define(
    ['jquery', 'ko', 'uiComponent', 'Magento_Ui/js/modal/modal', 'domReady!'],
    function($, ko, Component, modal) {
        'use strict';

        return Component.extend({

            initialize: function() {
                this._super();
            },

            defaults: {
                template: 'Vendor_Module/js-item',
                testVarThatPrintsTest: 'TEST TEST TEST@'

            }
        });
    }
);

I get the fallowing error:

Message: testVarThatPrintsTest is not defined
    at text (eval at createBindingsStringEvaluator (knockout.js:2624), <anonymous>:3:57)
    at update (knockout.js:4260)
    at ko.dependentObservable.disposeWhenNodeIsRemoved (knockout.js:3004)
    at evaluateImmediate (knockout.js:1737)
    at Object.ko.computed.ko.dependentObservable (knockout.js:1946)
    at knockout.js:3002
    at Object.arrayForEach (knockout.js:151)
    at applyBindingsToNodeInternal (knockout.js:2974)
    at applyBindingsToNodeAndDescendantsInternal (knockout.js:2854)
    at Object.ko.applyBindings (knockout.js:3065)

What is the problem here?

Best Answer

The problem was that the scope and the binding happened to a

element. Probably has something to do with the inline nature of the element and the fact that I was trying to add block elements(from the child component template) to the content of an inline element. When I changed the code to

<div data-bind="foreach: someArray, visible: someArray().length > 0 ">
    <div data-bind="scope: 'js_list.js_item'">
        <!-- ko template: getTemplate() --><!-- /ko -->
        <div data-bind="text: testVarThatPrintsTest"></div>
    </div>
</div>

Everything started working just fine.

Related Topic