orderby - order by number angularjs
Angularjs-utilizando el filtro orderby en el alcance del controlador (1)
Tengo una matriz de objetos, es decir, filtrada y paginada, y ahora me gustaría ordenar los elementos de la lista por diferentes atributos de objeto.
orderBy
filtro orderBy
siguiente manera:
<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>
Esto parece estar funcionando bien, al hacer clic en el enlace Title
, ordena la fila alfabéticamente o al revés alfabéticamente dependiendo del estado actual.
Pero el problema aquí es que solo se están pagedItems
los elementos pagedItems
, lo que tiene sentido ya que estamos aplicando el filtro orderBy
a los elementos pagedItems
. Lo que quiero lograr es pedir que se ordene todo el conjunto de elementos (no solo los elementos actualmente paginados) cuando se aplica el filtro.
Para lograr esto, pensé que usaría un método en el alcance del controlador. así que cambié lo anterior a:
/** 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'');
});
El método sortItems
funciona y cambia el orden, pero los elementos en la vista no se actualizan ya que el código $watch
no se activa. Supuse que tal vez no se haya modificado porque los datos en $scope.filtered
no se están modificando y solo se están cambiando los índices. Así que agregué y vacié un elemento al final de la matriz:
$scope.sortItems = function(value) {
$scope.filtered = $filter(''orderBy'')($scope.filtered, value);
$scope.filtered.push({});
};
Ahora, todo funciona como se esperaba pero no puedo mantener un objeto vacío en la matriz, ya que afecta los elementos, el recuento y los datos que se muestran. Así que pensé en agregar y eliminar un artículo vacío. Así que cambié lo anterior a:
$scope.sortItems = function(value) {
$scope.filtered = $filter(''orderBy'')($scope.filtered, value);
$scope.filtered.push({});
$scope.filtered.pop();
};
Pero adivina qué código de $watch
no se dispara nuevamente.
Pregunta
Mi pregunta es si $watch
busca cambios en una matriz en función de su longitud. Si es así, ¿cuál es la mejor manera de lograr lo que intento? Cualquier ayuda sería apreciada.
Ok, resolví esto usando $broadcast
y $on
siguiente manera:
$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'');
})