I'm implementing a custom grid that applies formatting for certain columns. When you click the "Toggle Sort" link, the second column does not track alongside the first column. However, removing "track by $index" fixes it. At first I understood that binding primitive data was the problem but that's not the case.
<div ng-app="testApp">
<div ng-controller="MyCtrl">
<h3>With Track By</h3>
<div ng-repeat="row in (filteredRows=(rows | orderBy:sort.column:sort.descending)) track by $index">
<span>{{ filteredRows[$index].s }}</span><fmt data-model="filteredRows[$index]"></fmt>
</div>
<br/>
<a href="#" ng-click="sort.descending = !sort.descending">Toggle Sort</a>
</div>
</div>
angular.module('testApp', [])
.controller('MyCtrl', function($scope) {
$scope.rows = [
{ v: 1.2345, s: 'foo' },
{ v: 0.1, s: 'bar' },
{ v: -3.33333, s: 'baz' },
{ v: 10, s: 'rar' }
];
$scope.sort = { column: 'v', descending: false };
})
.directive('fmt', function() {
return {
restrict: 'AE',
scope: {
model: '='
},
template: '<span style="display:inline-block;width:100px;text-align:right;">{{ model.v }}</span>' +
'<span style="display:inline-block;width:100px;text-align:right;">{{ fmtModel }}</span>',
controller: function($scope) {
$scope.fmtModel = $scope.model.v.toFixed(2);
}
};
})
The issue that is demonstrated in this fiddle: http://jsfiddle.net/4Hs36/5/
This is a workaround that seems to work: http://jsfiddle.net/4Hs36/6/. Here I'm attaching the formatted value directly to the model but I'm not so sure whether this is a good idea.
Hoping someone can shed more light on what's going on with "track by $index"?
There is something I didn't quite understand about scopes. I had the impression you could attach a property to $scope and it would update automatically when the bound value changes.
I updated the fiddle in the original post with this http://jsfiddle.net/4Hs36/7/
controller: function($scope) {
$scope.fmtModel = function() {
return $scope.model.v.toFixed(2);
}
}
I guess I could add a $watch and fix it that way: http://jsfiddle.net/4Hs36/8/
controller: function($scope) {
$scope.$watch('model.v', function() {
$scope.fmtModel = $scope.model.v.toFixed(2);
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With