Kaushal O
Kaushal O

Reputation: 47

Two array binding in one foreach loop in knockout JS

Please look at my view model below:

viewModel = [
 {
  StudentName : 'Ronald',
  Reviews : [ '3/5', '2/5', '4/5'],
  TeacherNames : [ 'Nema', 'Sarah', 'Vilson']
  },
 {
  StudentName : 'Chris',
  Reviews : [ '4.5/5', '2.5/5', '3.5/5'],
  TeacherNames : [ 'Nema', 'Sarah', 'Vilson']
 }
]

In below HTML I am trying to display Reviews in nested foreach structure. Reviews display as per expectation. but how can I place TeacherNames along with that single review? I have put the TeacherNames[$index], but it doesn't work.

Note 1: Number of elements in both the array(i.e. Reviews and TeacherNames) will be same.

Note 2: I don't want to change the structure of this JSON model, something like putting extra variable and placing both the parameters in one array.

<div data-bind="foreach:viewModel">
    <span data-bind="text: StudentName"></span>
     <ul data-bind="foreach:Reviews">
       <li>
         <a href="#" data-bind="text:$data">Inbox </a>
         <span class="ui-li-count" data-bind="text:TeacherNames[$index]">123</span>
       </li>
     </ul>
</div>   

Please check this Fiddle .

Upvotes: 4

Views: 5201

Answers (4)

Calvin
Calvin

Reputation: 181

EDIT: The scope (context) is wrong. You can access TeacherNames with $parent or $root.

Changed:

<span data-bind="text:TeacherNames[$index()]" >123</span>

To:

<span data-bind="text:$parent.TeacherNames[$index()]" >123</span>

http://jsfiddle.net/calvinslusarski/7xuKX/2/

Upvotes: -1

Paul Manzotti
Paul Manzotti

Reputation: 5147

Your property is called TeacherNames, but you are calling it as TeacherName.

Also, it is on the parent object, so try:

data-bind="text:$parent.TeacherNames[$index()]"

Upvotes: 1

Michael Best
Michael Best

Reputation: 16688

RoyalleBlue's answer is correct when using just the foreach binding. But using my Repeat binding will make your binding code much cleaner:

<ul>
  <li data-bind="repeat:Reviews.length">
    <a href="#" data-bind="text:Reviews[$index]"></a>
    <span data-bind="text:TeacherNames[$index]"></span>
  </li>
</ul>

http://jsfiddle.net/mbest/p2kHU/

Upvotes: 2

RoyalleBlue
RoyalleBlue

Reputation: 106

Think of it like this: $index is the observable, and $index() is the value of the observable. You need to give the TeacherNames array the number, not the observable.

Use

<span data-bind="text:$parent.TeacherNames[$index()]" >123</span>

instead of

<span data-bind="text:$parent.TeacherNames[$index]" >123</span>

to access the value $index().

I made a copy of your fiddle with the changes applied.

Also, thank you to Calvin, who just used this example to help me on the same question in a different format.

Upvotes: 3

Related Questions