1

I get the following error when I try to use getTemplate() within KnockoutJS foreach.

Message: Unable to process binding "with: function(){return getChild('my-child') }" Message: getChild is not defined. getChild is not defined

This is how my KOjs template looks...

<!-- ko foreach: myObj -->
<div>some markup...</div>
    <!-- ko with: getChild('my-child') -->
        <!-- ko template: getTemplate() --><!-- /ko -->
    <!--/ko-->
<!--/ko-->

I'm able to render the template outside of the foreach.

I've tried using $parent.getChild but this does not work.

I've also tried this with the more common getRegion method below, but without success:

<!-- ko foreach: getRegion('my-child-area') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->
1

3 Answers 3

4

Actually using the $parent context property worked fine. I also had a extra space typo in my child template file name, which I had missed when I first tried using $parent

<!-- ko foreach: myObj -->
<div>some markup...</div>
    <!-- ko with: $parent.getChild('my-child') -->
        <!-- ko template: getTemplate() --><!-- /ko -->
    <!--/ko-->
<!--/ko-->
1
  • 1
    The reason you need $parent is because within the foreach loop, you are within the context of the looping item. Without $parent, Knockout will be looking for that child element to contain a getChild prop, which it does not. Just thought this little tidbit may be useful! Jul 16, 2021 at 18:47
3

The getChild method exists only on UiComponents extending from uiComponent (a.k.a. uiCollection or Magento_Ui/js/lib/core/collection.
Maybe your component only extends from the uiElement (a.k.a. Magento_Ui/js/lib/core/element/element), which doesn't have getChild()?

1
  • Thanks! I also had a stupid typo. Answered my own question below.
    – Holly
    Jul 18, 2018 at 14:08
3

See the code in files and try like this.

grid.phtml

<div id="block-sample-grid" data-bind="scope:'sample-grid'" class="block">


    <!-- ko template: getTemplate() --><!-- /ko -->

    <script type="text/x-magento-init">

    {

        "#block-sample-grid": {

            "Magento_Ui/js/core/app": <?php /* @escapeNotVerified */ echo $block->getJsLayout();?>

        }

    }

</script>

</div>

grid.html

 <h2>Your seat reservations (<span data-bind="text: seats().length"></span>)</h2>

    <table>
        <thead><tr>
            <th>Passenger name</th><th>Meal</th><th>Surcharge</th><th></th>
        </tr></thead>
        <tbody data-bind="foreach: seats">
        <tr>
            <td><input data-bind="value: name" /></td>
            <td><select data-bind="options: $parent.availableMeals, value: meal, optionsText: 'mealName'"></select></td>
            <td data-bind="text: formattedPrice"></td>
            <td><a href="#" data-bind="click: function(data,event){$parent.removeSeat($parent,data);}">Remove</a></td>
        </tr>

        </tbody>

    </table>
    <button data-bind="click:addSeat, enable: seats().length < 5 ">Reserve another seat</button>

    <h3 data-bind="visible: totalSurcharge() > 0">
        Total surcharge: $<span data-bind="text: totalSurcharge().toFixed(2)"></span>
    </h3>

grid.js

define(
    [
        'jquery',
        'ko',
        'uiComponent',
    ],
    function ($, ko, component) {
        "use strict";
        function SeatReservation(name, initialMeal) {
            var self = this;
            self.name = name;
            self.meal = ko.observable(initialMeal);

            self.formattedPrice = ko.computed(function() {
                var price = self.meal().price;
                return price ? "$" + price.toFixed(2) : "None";
            });
        } 
        return component.extend({
            seats: ko.observableArray([]),
            availableMeals : ko.observableArray([]),
            addSeat : function() {
                var seat = new SeatReservation ("Your Name",this.availableMeals()[0]);
                this.seats.push(seat);
            },
            removeSeat : function(parent,seat) {
                parent.seats.remove(seat);

            },

            addMeal:function(meals){

                for (var i in meals){
                    this.availableMeals.push(meals[i]);
                }

            },


            totalSurcharge : function() {
                var total = 0;
                for (var i = 0; i < this.seats().length; i++)
                    total += this.seats()[i].meal().price;
                return total;
            },

            initialize: function () {

                this._super();
                this._render();
                this.totalfeeds();

            },
            _render:function(){

                var self = this;
                var meals = [
                    { mealName: "Standard (sandwich)", price: 0 },
                    { mealName: "Premium (lobster)", price: 34.95 },
                    { mealName: "Ultimate (whole zebra)", price: 290 }
                ];
                this.addMeal(meals);
                var init_seats = [
                    new SeatReservation ("Henry",this.availableMeals()[0]),
                    new SeatReservation ("Bert",this.availableMeals()[0]),

                ];
                for(var i in init_seats){
                    this.seats.push(init_seats[i]);
                }
            },
            defaults: {
                template: 'Thienphucvx_Knockout/grid',
            },
        });
    }
);

Your Answer

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

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