Angularjs - использование фильтра порядка в области действия контроллера

У меня есть массив объектов, т.е. отфильтрованных и выгружаемых, и теперь я хотел бы упорядочить элементы списка по разным атрибутам объекта.

Я попробовал фильтр orderBy следующим образом:

<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>

Кажется, это работает нормально, щелкнув ссылку Title, упорядочивает строку в алфавитном порядке или наоборот в алфавитном порядке в зависимости от текущего состояния.

Но проблема здесь в том, что упорядочиваются только pagedItems, что имеет смысл, поскольку мы применяем фильтр orderBy к pagedItems. Чего я хочу добиться, так это упорядочить весь набор элементов (а не только элементы, выгружаемые в данный момент), когда фильтр применяется.

Чтобы добиться этого, я подумал, что буду использовать метод в области действия контроллера. поэтому я изменил вышеизложенное на:

/** 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');
});

Метод sortItems работает и меняет порядок, но элементы в представлении не обновляются, так как код $watch не запускается. Я предположил, что, возможно, он не изменяется, потому что данные в $scope.filtered не изменяются, а изменяются только индексы. Поэтому я добавил пустой элемент в конец массива:

$scope.sortItems = function(value) {
    $scope.filtered = $filter('orderBy')($scope.filtered, value);
    $scope.filtered.push({});
};

Теперь все работает так, как ожидалось, но я не могу сохранить пустой объект в массиве, так как он влияет на отображаемые элементы, количество и данные. Поэтому я подумал, что добавлю и удалю пустой элемент. Поэтому изменил вышеизложенное на:

$scope.sortItems = function(value) {
    $scope.filtered = $filter('orderBy')($scope.filtered, value);
    $scope.filtered.push({});
    $scope.filtered.pop();
};

Но угадайте, что код $watch больше не срабатывает.

Вопрос

Мой вопрос: ищет ли $watch изменения в массиве на основе его длины? Если да, то каков наилучший способ добиться того, что я пытаюсь сделать. Любая помощь будет оценена по достоинству.


person Amyth    schedule 17.12.2013    source источник


Ответы (1)


Хорошо, я решил это, используя $broadcast и $on следующим образом:

$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');
})  
person Amyth    schedule 17.12.2013