1
votes

I have a problem with KnockoutJS, where the $parent binding context is undefined.

Code

<div class="row">
    <div class="col-md-4">
        <div class="panel panel-info">
            <div class="panel-heading">
                <h2 class="panel-title">Products Data</h2>
            </div>
            <div class="panel-body">
                <table class="table table-striped table-bordered table-condensed" data-bind="with: ProductsViewModel">
                    <thead>
                        <tr>
                            <th>ProductID</th>
                            <th>Product Name</th>
                            <th>Units In Stock</th>
                            <th>Action</th>
                        </tr>
                    </thead>
                    <tbody data-bind="foreach: products">
                        <tr>
                            <td data-bind="text: $data.ProductID"></td>
                            <td data-bind="text: $data.ProductName"></td>
                            <td data-bind="text: $data.UnitsInStock"></td>
                            <td><button class="btn btn-danger btn-xs" data-bind="click: $parent.RemoveProduct">[x] delete</button></td>
                        </tr>
                    </tbody>
                </table>
                <button class="btn btn-large" data-bind="click: GetProducts()">Load Data</button>
            </div>
        </div>
    </div>
</div>

and:

/// <reference path="../Scripts/knockout-3.4.0.js" />
/// <reference path="../Scripts/jquery-1.10.2.js" />

function ProductsViewModel() {
    var self = this;

    self.products = ko.observableArray([]);

    self.RemoveProduct = function () {
        bootbox.alert({ message: 'Pressed !!', size: 'small' });
    }

    self.GetProducts = function () {
        self.products.removeAll();

        $.getJSON('/api/products', function (data) {
            $.each(data, function (key, value) {
                self.products(data);
            });
        });
    }
}

$(document).ready(function () {
    ko.applyBindings(ProductsViewModel);
});

All the binding work correctly in the table, except the click event binding on the button, where the $parent is undefined.

If I remove the button control all the data binds correctly in the table element.

Any ideas how to fix this ?? It's all standard Knockout code to my knowledge.

Thanks in advance.

bax2097

I've fixed this by removing the $parent altogether. All working now.

1
What specific error messages are you seeing?James Thorpe
This is the exception message: Unhandled exception at line 3326, column 21 in localhost:51496/Scripts/knockout-3.4.0.debug.js 0x800a138f - JavaScript runtime error: Unable to get property 'RemoveProduct' of undefined or null reference I think this suggests that $parent is undefinedbax2097
I've tried using $route as well, $route.ProductsViewModel.RemoveProduct, with the same resultbax2097
Fixed, comment addedbax2097
Anyone knows why removing the $parent fixes the issue? Encountered a similar issue.jibin mathew

1 Answers

0
votes

Problems

  1. In your Html you bind your table into a with: ProductsViewModel. Which is not needed.

  2. In your Load data button you did not pass the actual function, instead you execute it right away, so just remove ().

See this JsFiddle for demo