Angularjs - 在控制器范围内使用 orderby 过滤器



我有一个对象数组,即过滤和分页,现在我想按不同的对象属性对列表项进行排序。

我尝试了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是否根据数组的长度来查找数组中的变化?如果是的话,实现我所努力的目标的最佳方式是什么。任何帮助都将不胜感激。

好的,我使用$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');
})  

最新更新