【问题标题】:Sorting elements in AngularJS for nested ng-repeat在 AngularJS 中为嵌套的 ng-repeat 排序元素
【发布时间】:2016-07-13 14:12:35
【问题描述】:

我正在使用引导程序显示项目网格,每行有 3 列。为了做到这一点,我使用 ng-repeat 两次,如下所示。

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

我希望能够根据项目的标题字段对项目进行排序。应用过滤器仅对整个列表的子集进行排序,即在块级别而不是项目级别进行排序。

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

orderBy 发生后,行是 A M Z,A M Z。如何让它显示 A A M,M Z Z?

这是上述问题的plunk。 //EDIT : 上面的 plunk 指向解决方案,因为我更新了 plunk。

【问题讨论】:

  • 为什么你会期望内部 ng-repeat 上的排序会影响外部?要么在外部排序,要么考虑将您的数据结构扁平化为更类似于您的输出的东西。
  • 是的,您需要进一步扁平化结构。
  • 据我了解,您建议我将项目修改为 var = [{"title":"A"},{"title:"B"},{"title":"C "},{"title":"A"},{"title:"B"},{"title":"C"}]。这产生了另一个问题。我希望具有类行的外部 div 恰好包含三个具有类 col-sm-4 的内部 div。建议的数据结构无法实现。

标签: angularjs twitter-bootstrap angularjs-filter angularjs-orderby


【解决方案1】:

您需要一个自定义过滤器,将您的子数组转换为单个数组。拥有单独数组的全部意义在于隔离内容,这与您想要的相反。

过滤器:

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;
    };
} ...

现在你的视图可以是这样的:

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

【讨论】:

  • 我希望具有类行的 div 恰好包含 3 个具有类 col-sm-4 的 div。因此,如果项目变量中有 3 个以上的项目,我希望额外的项目进入一个带有类行的新 div。
  • @PravinUmamaheswaran 我对其进行了编辑以在排序后重新拆分整个数组。
  • 我尝试了您编辑的解决方案。我收到 $rootScope.infdig 错误。事实证明,每次调用过滤器时,ng-repeat 的模型都会不断变化,这导致 $digest 被无限次调用。我正在尝试使用 $scope.$watch 来解决这个问题。如果我找到解决方案会更新。
  • 好的,这听起来像是过滤器外部的问题。我最终给出的只是在一个孤立的范围内进行了一些非常简单的重新排列。
【解决方案2】:

我最终通过过滤器链接解决了这个问题。我使用了角度过滤器模块/库,但这甚至可以在没有角度过滤器的情况下完成。

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

我将数组展平,使其看起来像这样。

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

在过滤器链中,我首先按标题对展平数组中的元素进行排序,然后将其划分为每个包含 3 个元素的子数组。希望这会有所帮助。

你可以找到plunkhere

【讨论】:

    【解决方案3】:

    试试这个。可能对你有帮助。

    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>

    【讨论】:

    • 我对 Angular js 很陌生,我不太了解 angular.forEach() 代码块。我尝试按原样使用此代码,但不会打印网格列。我不知道我是不是搞砸了。
    猜你喜欢
    • 2015-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-23
    • 2016-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多