Reputation: 9587
I'm trying to create a nested ng-repeat
loop. It uses the groupBy
and toArray
filters from angular-filter.
The issue is that I have an editable input field in the nested array. Without implementing "track by" on the ng-repeats every time the value changes when typed it looses focus as described in this issue.
If I try to put a track by
on the repeats it breaks and shows many fields with blank values. Is there any way to correctly implement track by
in this situation so that the repeats display correctly and I can type into the input field without it losing focus?
Here is example, if you run it you will see as soon as you edit input you loose focus:
var app = angular.module('App', ['angular.filter']);
app.controller('MainCtrl', function() {
this.Parts = [{
Id: 1,
ShortDescription: "Premium Shocks",
SupplierSku: "ZXU3322",
SellPrice: 110,
SellPriceInclGst: 130,
ProfitExclGst: 10,
SupplierName: 'Super Sports',
Quantity: 3
}, {
Id: 2,
ShortDescription: "Spanner",
SupplierSku: "4444",
SellPrice: 44,
SellPriceInclGst: 130,
ProfitExclGst: 10,
SupplierName: 'Bobs Parts',
Quantity: 1
}, {
Id: 3,
ShortDescription: "Spark Plugs",
SupplierSku: "xxxxx",
SellPrice: 10,
SellPriceInclGst: 130,
ProfitExclGst: 10,
SupplierName: 'Bobs Parts',
Quantity: 5
}]
});
<html>
<head>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-filter/0.5.4/angular-filter.min.js"></script>
</head>
<body ng-app="App">
<table class="table" ng-controller='MainCtrl as main'>
<thead>
<tr>
<th>Short Descriptin</th>
<th>SKU</th>
<th>Qty</th>
<th>Unit Price</th>
<th>Total</th>
<th>Total + GST</th>
</tr>
</thead>
<tbody ng-repeat="supplier in main.Parts | groupBy:'SupplierName' | toArray:true | orderBy:'$key'">
<tr class="title-display-row">
<td colspan="6">{{ supplier.$key }}</td>
</tr>
<tr ng-repeat="item in supplier track by $index">
<td>{{ item.ShortDescription }} {{ key }}</td>
<td>{{ item.SupplierSku }}</td>
<td class="field-cell">
<div class="field-wrap">
<input type="text" name="quantity[$index]" ng-model="item.Quantity" />
</div>
</td>
<td>{{ item.SellPrice | currency }}</td>
<td>Total</td>
<td>Total-gst</td>
</tr>
</tbody>
</table>
</body>
</html>
Any suggestions greatly appreciated.
Upvotes: 1
Views: 579
Reputation: 9587
In the unlikely event someone has the same problem as this... the solution was to remove the toArray|true
filter.
Then instead of accessing the supplier name with {{ supplier.$key }}
I'm using {{ Supplier[0].SupplierName }}
. Because each supplier
in the loop is an array of items with the same supplier name so I can just take the first and use it.
Upvotes: 2