2013-12-17 13 views
8

Ho una matrice di oggetti, ad esempio filtrata e paginata, e ora desidero ordinare gli elementi della lista in base a diversi attributi dell'oggetto.Angularjs - utilizzo del filtro orderby nello scope del controller

Ho provato il filtro orderBy come segue:

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

Questo sembra funzionare bene, cliccando sul link Title, ordina la riga alfabetico oppure invertire alfabetico seconda dello stato attuale.

Ma il problema qui è che viene ordinato solo il pagedItems, il che ha senso visto che stiamo applicando il filtro orderBy allo pagedItems. Quello che voglio ottenere è ordinare l'intero set di elementi (non solo gli oggetti attualmente paginati) da ordinare quando il filtro viene applicato.

Per ottenere ciò, ho pensato di utilizzare un metodo nell'ambito del controller. così ho cambiato la precedenza 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'); 
}); 

I sortItems opere di metodo e di modificare l'ordine, ma gli elementi nella vista non si aggiorna il codice $watch non viene generato. Ho pensato che forse non è stato modificato perché i dati nello $scope.filtered non sono stati modificati e solo gli indici sono stati modificati. Così ho aggiunto ed elemento vuoto alla fine della matrice:

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

Ora, tutto funziona come previsto, ma non riesco a tenere un oggetto vuoto nella matrice, poiché colpisce gli elementi, contare e dati che vengono visualizzati. Quindi ho pensato di aggiungere e rimuovere un oggetto vuoto. Così modificato il precedente per:

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

Ma indovinate un po ', non il codice $watch essere di nuovo licenziato.

Domanda

La mia domanda è non $watch sguardo per le modifiche in un array basa su di essa la lunghezza? Se sì, qual è il modo migliore per ottenere ciò che sto cercando di fare. Qualsiasi aiuto sarebbe apprezzato.

risposta

5

Ok ho risolto questo utilizzando $broadcast e $on come segue:

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