Ehud Kaldor
Ehud Kaldor

Reputation: 793

how to write a generic sort in angularjs

I am writing an angular.js application, and i need to do a filter-orderBy on a JSON array. if i do it by creating a method that takes no parameters and refers to the explicit array with $scope, everything works fine:

...
<th class="ui th" ng-click="sortArray('name')">Name</th>
...

sortArray = (sortParam) ->
  $scope.myArray = $filter('orderBy')($scope.myArray, sortParam)

but if i try to generify it by having the array as a method parameter, like this:

...
<th class="ui th" ng-click="sortArray(myArray,'name')">Name</th>
...

sortArray = (arr,sortParam) ->
  arr = $filter('orderBy')(arr, sortParam)

it seems like the array is sorted in the backend, but the table that uses it for ng-repeat stays unchanged, visually. example: i have this array:

{ arr : 
 [
  { 'id' : 1 },
  { 'id' : 2 },
  { 'id' : 3 }
 ]
}

now, in the first case, if i sort with the first case, the rendering changes to match the sorted array. but in the second case, the rendering will not change (it will still show as 1 - 2 - 3), but if i have it print the id of the first cell (which renders '1') it will say '3' (the top of the array after sorting. hope it makes sense.

the reason i need it is to open a modal with the content of the row clicked. for that, i put an ng-click in the ng-repeat tag, with the index:

<tr ng-repeat="row in arr | filter:filter" ng-click="loadModal($index)">

that way, even if the array is reordered, the value of loadModal($index) does not change, in will open with the correct row.

so, after this long explanation - how do i write a generic method that can take and order different array (code reuse) but affects the rendering too? or, is this the right way to even do so? i don't have an ID for the entries of the array, and there is nothing natural i can cling to, to identify the row.

Upvotes: 1

Views: 378

Answers (1)

Tasnim Reza
Tasnim Reza

Reputation: 6060

I think you don't need to write a generic method!

Use the orderBy filter with ng-repeat in your view like

<tr ng-repeat="friend in friends | orderBy:predicate:reverse">

And on ng-click set the predicate value like

<th class="ui th" ng-click="predicate = 'name'; reverse= !reverse">Name</th>

When you click Name the predicate will pass the value to orderBy filter and your view adjust the latest change automatically, reverse= !reverse used for toggle your sort.

Check the angularjs Demo

Upvotes: 1

Related Questions