Sorting elements in AngularJS for nested ng-repeat

2019-09-19 17:32发布

问题:

I am using bootstrap to display a grid of projects with each row having 3 columns. In order to accomplish this, I am using ng-repeat twice like below.

<div class="row" ng-repeat="chunk in projects">
  <div class="col-sm-4" ng-repeat="project in chunk | orderBy:'title'">
    {{project.title}}
  </div>
</div>    

I want to be able to sort the project based on its title field. Applying a filter only sorts a subset of the whole list i.e. sorts at the chunk level rather than the projects level.

var projects = [[{"title":"Z"},{"title":"A"},{"title":"M"}],
  [{"title":"Z"},{"title":"A"},{"title":"M"}]];

After the orderBy happens, the rows are A M Z, A M Z. How do I get it to display A A M, M Z Z?

Here is the plunk for the above problem. //EDIT : The above plunk points to the solution because I updated the plunk.

回答1:

You'll need a custom filter that will turn your sub-arrays into a single array. The whole point of having separate arrays would be to isolate the contents, which is the opposite of what you want.

Filter:

yourAppModule
.filter('titleSort', function(){
    return function(input){
        var fullArray = []; //Will be the output array    
        for(var i=0;i<input.length;i++)            
            fullArray.concat(input[i]);
            //Iterates through all the arrays in input (projects)
            //and merges them into one array            
        fullArray = fullArray.sort(function(a,b){return a.title>b.title});
            //Sorts it by the title property
        var chunks = [];
        var currentChunk;
        for(var i=0;i<fullArray.length;i++){
            if(i%3===0){
                currentChunk = [];
                chunks.push(currentChunk);
            }
            currentChunk.push(fullArray[i]);   
        }
        return chunks;
    };
} ...

Now your view can be this:

<div class="col-sm-4" ng-repeat="project in projects | titleSort">
    {{project.title}}
</div>


回答2:

I was able to solve this problem finally through filter chaining. I used angular-filter module/library but this can be even done without angular-filter.

<div class="container" ng-controller="ExampleController as exampleVm">
<div class="row" ng-repeat="chunk in exampleVm.projects|  chunkBy: 'title' | groupBy : 3">
  <div class="col-sm-4" ng-repeat="project in chunk">
    {{project.title}}
  </div>
</div>

I flattened the array and made it look like this.

var projects = [{"title:Z"},{"title":"A"},{"title":"M"},{"title:Z"},{"title":"A"},{"title":"M"}]

In the filter chain, I order the elements in the flattened array first by title and then divide it into subarrays of 3 elements each. Hope this helps.

You can find the plunk here.



回答3:

try this. may be help you.

var app = angular.module("app",[])
app.controller('ctrl',['$scope', function($scope){
        $scope.data = [[{"title":"Z"},{"title":"A"},{"title":"M"}],
  [{"title":"Z"},{"title":"A"},{"title":"M"}]];
  
  $scope.data2 = [];
  angular.forEach( $scope.data,function(d){
    angular.forEach(d,function(d1){
      $scope.data2.push(d1);
      })
    })
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<div ng-app="app" ng-controller="ctrl">
<div class="item item-checkbox">
   <div class="row">
  <div class="col-sm-4" ng-repeat="project in data2 | orderBy:'title'">
    {{project.title}}
  </div>
</div>    
</div>