user3460350
user3460350

Reputation: 9

nested foreach loop when the inner loop array has more than one field

what changes are to be made to view and the viewmodel in the following example if the children array has two more fields "child age" and "weight".

view:

 <h2>People</h2>
<ul data-bind="foreach: people">
<li>
    <div>
        <span data-bind="text: name"> </span> has <span data-bind='text: children().length'>&nbsp;</span> children:    
    </div>
    <ul data-bind="foreach: children">
        <li>
            <span data-bind="text: $data"> </span>                
        </li>
    </ul>
</li>

viewmodel:

var Person = function(name, children) {
this.name = name;
this.children = ko.observableArray(children);

this.addChild = function() {
    this.children.push("New child");
}.bind(this);
 }

var viewModel = {
people: [
    new Person("Annabelle", ["Arnie", "Anders", "Apple"]),
    new Person("Bertie", ["Boutros-Boutros", "Brianna", "Barbie", "Bee-bop"]),
    new Person("Charles", ["Cayenne", "Cleopatra"])
    ],
};

ko.applyBindings(viewModel);

Upvotes: 0

Views: 93

Answers (2)

Scott Murphy
Scott Murphy

Reputation: 448

You can add additional properties to the children array by making it an array of objects instead of just an array of strings like so:

new Person("Annabelle", [
    {Name: "Arnie", weight: 25, age: 2}, 
    {Name: "Anders", weight: 45, age: 5}, 
    {Name: "Apple", weight: 29, age: 2}])

and the html change like so:

<span data-bind="text: $data.Name"></span>    
<ul>
    <li data-bind="text: $data.weight +'lbs. '"/>
    <li data-bind="text: $data.age + ' years'"/>
</ul>

Check out this jsfiddle with a working solution.

Upvotes: 1

Origineil
Origineil

Reputation: 3118

Obviously, the children would need to be objects. You could potentially reuse Person if you intend for it to also contain those properties.

[{name:"Arnie", age: 1, weight: 2}]

Then you bind to the properties:

<span data-bind="text: name"> </span> 
<span data-bind="text: age"> </span> 
<span data-bind="text: weight"> </span> 

Furthermore, you could use the 'as' aliasing feature of the foreach binding to make the HTML clearly reflect where the information is coming from

<ul data-bind="foreach: {data: children, as 'child'}">

The bindings for the child properties would take on the format

<span data-bind="text: child.name"> </span> 

See this fiddle for reference.

Upvotes: 1

Related Questions