14

Why is it, that when I try to use knockout.js to bind some text using $index, I get the code of a function instead of a number?

<tbody  data-bind="foreach: MyList">
  <tr>
    <td><span data-bind="text: $index + 1"></span></td>
  </tr>
</tbody>

Instead of getting 1, 2, 3 etc., I get this:

enter image description here

You can see, by the last character in the above image, that my index of zero is being added to 1. If I remove the '+ 1' from my binding, I get 0, 1, 2 instead of the function.

How do I tell knockout to evaluate the expression? I have the same issue when I submit the form. My string fields are being submitted as a function instead of the value.

rboarman
  • 8,248
  • 8
  • 57
  • 87

2 Answers2

32

$index is an observable, which is a function. Try <span data-bind="text: $index() + 1"></span>

John Earles
  • 7,194
  • 2
  • 37
  • 35
  • That fixed it. Why doesn't the documentation have examples with parens? http://knockoutjs.com/documentation/binding-context.html – rboarman Jul 02 '12 at 23:31
  • 2
    It's a general issue when using observables in expressions. If you are using the observable by itself the bindings will accept the observable alone, but when you start including observables in expressions you have to use the () form to access the actual value. See http://knockoutjs.com/documentation/observables.html for 'Reading and writing observables'. – John Earles Jul 02 '12 at 23:54
4

If you use

<span data-bind="text: $index() + 1"></span> 

and for example your index value is 2, the text of your span will be: 21 and not 3.

you should define a function in your viewModel, like this:

self.itemNumber = function(index) {
    return index + 1;
}

and then in your span you should do:

<span data-bind="text: $root.itemNumber($index())"></span>

I hope this will help :)

Donatella
  • 41
  • 2
  • +1 for the simple fact that if the index is 2, then by using the accepted answer technique you get 21, 23 or so instead of 3, 4 ecc. I don't understand how the accept answer was accepted, it's just wrong (at least with knockout 2.2.1). – firepol Apr 10 '13 at 12:54
  • Here is a jsFiddle...it seems to work with both methods :S http://jsfiddle.net/BAEsx/24/ – Donatella Apr 16 '13 at 11:32