Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angularjs - using orderby filter in the controller's scope

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.

like image 802
Amyth Avatar asked Dec 17 '13 10:12

Amyth


People also ask

What is orderBy filter in AngularJS?

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.

What is correct way to apply multiple filters in AngularJS?

Answer: A is the correct option. The syntax of applying multiple filters in AngularJS can be written as: {{ expression | filter1 | filter2 | ... }}

What is the correct way to apply filter in angular?

Filters can be added to expressions by using the pipe character | , followed by a filter.

How do I sort numbers in AngularJS?

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 .


1 Answers

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');
})  
like image 70
Amyth Avatar answered Nov 07 '22 23:11

Amyth