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-->
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()?

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

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-->
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, privacy policy and cookie policy

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