I have an array of objects i.e. filtered and paged and now I would like to order the list items by different object attributes.
I tried the orderBy
filter as follows:
<th><a href='' ng-click="reverse = sortParam == 'title' && !reverse; sortParam = 'title'">Title</a></th>
<tr ng-repeat="item in pagedItems|filter:filterParam|orderBy:sortParam:reverse">
<td>{{ item.title }}</td>
</tr>
This seems to be working fine, clicking on the Title
link, orders the row alphabetically or reverse alphabetically depending on the current state.
But the problem here is that only the pagedItems
are being ordered, which makes sense as we are applying the orderBy
filter to the pagedItems
. What I want to achieve is to order the whole set of items (not just currently paged items) to be ordered when the filter is applied.
In order to achieve this I thought i'd use a method in the controller scope. so I changed the above to:
/** In the Template */
<th><a href='' ng-click="sortItems('title')">Title</a></th>
<tr ng-repeat="item in pagedItems|filter:filterParam">
<td>{{ item.title }}</td>
</tr>
/** In the Controller */
$scope.sortItems = function(value) {
$scope.filtered = $filter('orderBy')($scope.filtered, value);
};
$scope.$watch('currentPage + numPerPage + filtered', function() {
$scope.pagedItems = getPagedItems($scope, 'filtered');
});
The sortItems
method works and changes the order but the items in the view does not get updated as the $watch
code is not fired. I assumed that maybe it's not being changed because the data in the $scope.filtered
is not being altered and just the indexes are being changed. So I added and empty element at the end of the array:
$scope.sortItems = function(value) {
$scope.filtered = $filter('orderBy')($scope.filtered, value);
$scope.filtered.push({});
};
Now, Everything works as expected but I can't keep an empty object in the array as it affects the items, count and data being displayed. So I thought I'd add and remove an empty item. So changed the above to :
$scope.sortItems = function(value) {
$scope.filtered = $filter('orderBy')($scope.filtered, value);
$scope.filtered.push({});
$scope.filtered.pop();
};
But guess what the $watch
code not being fired again.
Question
My question is does $watch
look for changes in an array based on it's length ? If yes, what is the best possible way to achieve what I'm trying to. Any help would be appreciated.
An orderBy Filter in AngularJS is used to sort the given array to the specific order. The default order of sorting the string is in alphabetical order whereas the numbers are numerically sorted. By default, all the items are sorted in ascending order, if the ordering sequence is not specified.
Answer: A is the correct option. The syntax of applying multiple filters in AngularJS can be written as: {{ expression | filter1 | filter2 | ... }}
Filters can be added to expressions by using the pipe character | , followed by a filter.
To sort in descending order, set it as true . You can also use + to sort the data in an ascending and – the data in descending order also . Here with the filters in Angular JS, instead of displaying the various rows, we will be sorting it by ascending and descending order .
Ok I solved this using $broadcast
and $on
as follows:
$scope.sortList = function(value) {
if (value === $scope.currentFilter) {
value = value.indexOf('-') === 0 ? value.replace("-","") : "-" + value;
}
$scope.currentFilter = value;
$scope.filtered = $filter('orderBy')($scope.filtered, value);
$scope.$broadcast('sorted');
}
$scope.$on('sorted', function() {
$scope.pagedCandidates = getPagedItems($scope, 'filtered');
})
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