Sprottenwels Sprottenwels - 7 days ago 4
AngularJS Question

Using $index for ng-model

I am building a SPA where one can add a table-row on button-click:

<!-- Table -->
<table>
<tr>
<th>Lieferscheinnummer</th>
<th>Stück</th>
</tr>

<tr ng-repeat="position in positions">
<td><input type="text"></td>
<td><input type="text"></td>
</tr>
</table>

<!-- button -->
<span ng-click="addPosition()"></span>


Controller

$scope.positions = ['1'];
$scope.addPosition = function(){
$scope.positions.push( $scope.positions.length + 1 );
}


Now I have to apply an unique
ng-model
to each
<td>
of every row in order to send the given input to my database.

I searched for a solution and stumbled over
ng-repeat
's
$index
.
Unfortunately,
$index
seems to be not available for element attributes:

<tr ng-repeat="position in positions">
<td><input type="text" ng-model="{{$index +1}}"></td> <!-- does not work -->
<td><input type="text"></td>
</tr>


How would I apply an unique
ng-model
to each row while using
ng-repeat
?

Answer

You could change your model. Currently, you are using the ng-repeat like a counter. You have a model that stores the elements - you are not using the elements in anyway, just making use of the number of elements in the list and looping that many times.

What you could instead do is have a list of unique models itself.

Considering that you are using it inside a table, each entry could have an ID field to uniquely identify each row.

Thus, your model would look something like this:

//Will contain the data entered in the table
$scope.tableData = [
    {
        id: 1,
        data: ""
    },
    {
        id: 2,
        data: ""
    }
];

//Will keep track of the last used ID
$scope.currentId = 2;

//Will add a record to the table each time it is called
$scope.addRecord = function () {
    var newRecord = {
        id: $scope.currentId++;
        data: ""
    };
    $scope.tableData.push(newRecord);
};

In your view, you can now use tableData to loop over the actual data itself rather than the count of the records:

<tr ng-repeat="entry in tableData">
    <td>
        <input type="text" ng-model="entry.data">
    </td>
</tr>

For another input, you could simply add another attribute to each record. ng-repeat will create a scope for each record so entry.data will always point to the data attribute for the record located at that row.

Note: For an ID, you may have to use another approach of generating unique Ids for large amounts of records. Simply increment a counter will not be the best approach.