TheLazyChap
TheLazyChap

Reputation: 1902

KO - foreach binding does not seem to bind but I can't work it out

I am the process of learning Knockout JS. I'm going through some of John Papa's tutorial on Pluralsight regarding Knockout and Javascript.

The <div data-bind="text: people().length" class="label"> section seems to be working no problems. However the foreach binding seems to have issue.

What I've tried and done:

  1. I'm checked the Javascript code and Markpup and compared it to his and I see no difference.
  2. I looked at the developer tools error console in Chrome. No errors occurred.
  3. Binding a simple text property to an observable it works.
  4. Binding a hard code observableArray to the mark-up and it works.

JS

    $(function () {
    var Person = function (name) {
        this.name = ko.observable(name);
    };

    var viewModel = (function () {
        var p1 = new Person('Da Vinci');
        var p2 = new Person('Michangelo');
        var people = ko.observableArray([p1, p2]);
        return {
            people: people
        };
    })();

    ko.applyBindings(viewModel);
});

HTML Markup

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Knockout</title>
    <link href="../Content/bootstrap.css" rel="stylesheet" />
</head>
<body>
    <h1>Hello Knockout!</h1>
    <section>
        Records: 
        <div data-bind="text: people().length" class="label">
            <ul data-bind="foreach: people">
                <li>
                    <span data-bind="text: name"></span>
                </li>
            </ul>
        </div>
    </section>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.2.1.js"></script>
    <script src="../Js/ViewModel/AuthorCart.js"></script>
</body>
</html>

I am getting the following result but I'm expecting the two person name ('Da Vinci' and 'Michangelo') to appear underneath the records.

Hello Knockout!

Records: 2

Upvotes: 0

Views: 915

Answers (2)

akatakritos
akatakritos

Reputation: 9858

<div data-bind="text: people().length" class="label">
            <ul data-bind="foreach: people">
                <li>
                    <span data-bind="text: name"></span>
                </li>
            </ul>
        </div>

When you bind the count, you replace the entire contents of the div with "2", that likely includes overwriting the ul contained therein so that it is never able to be bound.

Can you try this:

<span data-bind="text: people().length" class="label"></span>
          <ul data-bind="foreach: people">
                <li>
                    <span data-bind="text: name"></span>
                </li>
            </ul>

Upvotes: 2

RP Niemeyer
RP Niemeyer

Reputation: 114792

The text binding that you have on the containing div is overwriting the children of the element, so your foreach is gone.

You would want to close off the container first:

  <div data-bind="text: people().length" class="label"></div>
  <ul data-bind="foreach: people">
       <li>
           <span data-bind="text: name"></span>
       </li>
  </ul>

Upvotes: 3

Related Questions