Accessing Item Index in foreach binding
We often want to use the index of a current item in an array. For example, if we want to show the serial number along with the array item. Knockout provides a better way to access the index of items in an array, whether it is a normal array or an observable array.
The syntax $index / $index() provides the way to access the index of the current item in the array. But its value is only accessible within the context of the foreach block. $index is an observable and is updated whenever the index of the item changes.
Index |
Item |
value of $index for each Item in foreach binding |
0 |
Item1 |
$index / $index() = 0 |
1 |
Item2 |
$index / $index() = 1 |
2 |
Item3 |
$index / $index() = 2 |
3 |
Item4 |
$index / $index() = 3 |
4 |
Item5 |
$index / $index() = 4 |
For example: If we want to show the employee name with serial number (index number) as in the following.
ViewModel
<script type="text/javascript">
function viewModelEmployee() {
this.Employees = ko.observableArray([
{ Name: "Shiv", Code: "001" },
{ Name: "DJ", Code: "002" },
{ Name: "Rajneesh Rai", Code: "003"}
]);
}
var vmEmp = new viewModelEmployee();
$(function () {
ko.applyBindings(vmEmp);
});
</script>
View
<table border="1">
<thead>
<tr>
<td>
Sr#
</td>
<td>
Employee Name
</td>
</tr>
</thead>
<tbody data-bind="foreach: Employees">
<tr>
<td data-bind="text : $index">
</td>
<td data-bind="text:Name">
</td>
</tr>
</tbody>
</table>
But the received result is not practical, since the serial number must start with 1. To do this we would use $index() + 1 as in the following:
<table border="1">
<thead>
<tr>
<td>
Sr#
</td>
<td>
Employee Name
</td>
</tr>
</thead>
<tbody data-bind="foreach: Employees">
<tr>
<td data-bind="text : $index() + 1">
</td>
<td data-bind="text:Name">
</td>
</tr>
</tbody>
</table>
We have now accomplished our goal, in other words Serial number.
Precautions
1. If you just want to use an index then you can use either $index or $index().
2. If you want to use an index to append or add something to the index then use $index(). Otherwise if you use it like $index + 1 then something weird happens, it does not provide the intended result.
Possible use-case scenarios might be:
data-bind=; 'EmpID ' + ($index() + 1) |
EmpID 1 |
DO Use |
data-bind=" $index() + 1" |
1 |
DO Use |
data-bind=" 'EmpID ' + ($index + 1)" |
Unexpected |
DON'T Use |
data-bind=" $index + 1" |
Unexpected |
DON'T Use |