【问题标题】:Horizontal ng-repeat(er) with new row breaks带有新换行符的水平 ng-repeat(er)
【发布时间】:2016-08-04 20:15:30
【问题描述】:

使用 Bootstrap 和 AngularJS,有没有办法在水平方向 ng-repeat 为每个设定数量的元素添加一个新行?

我一直在玩 ng-class 来完成这个 Fiddle,但问题是我无法在初始行 div 中获得浮动左 div...任何想法,我是不是没有想到什么,还是最好通过指令来完成?

这是我的代码(上面小提琴链接中的实时示例):

<body ng-app="myApp">
    <div ng-controller="MyCtrl">
        <div ng-repeat="num in numbers" 
            ng-class="{'row': ($index)%2==0, 'col-md-6': ($index)%2!=0}">
            <div ng-class="{'col-md-6': ($index)%2==0}">
                {{num}}
            </div>
        </div>
    </div>
</body>
var myApp = angular.module('myApp', [])
    .controller('MyCtrl', function ($scope) {
        $scope.numbers = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"];
});
.row {
    clear: both;
    width: 100%;
    border: 1px solid red;
}
.col-md-6 {
    width: 50%;
    float: left;
    border: 1px solid blue;
}

【问题讨论】:

  • 我不确定我是否理解您想要的最终结果。
  • 我是。我对 Foundations 更熟悉,但概念相同。我猜你现在使用的格式似乎没有传达这一点。让我弹奏小提琴。
  • @EnigmaRM 我删除了我的评论,因为我认为我可以更好地解释它,但你在我添加它之前回答了它,所以我将不理会它。我开始认为这是不可能的,因为转发器元素在 AngularJS 1.1.5(我正在使用的)中有一个结束标签,AngularJS 1.2 有一个可以解决这个问题的结束转发器标签,我在等待一个稳定的释放,但我可能不得不跳起来并修复我所有的动画。如果您找到解决方案,请告诉我。谢谢。
  • 不要放弃,有可能。确实,在 1.1.5 中有一个 ng-repeat-startng-repeat-end(或类似的东西)。不过,我还没有发现需要使用它。而且 1.1.5 也不是一个稳定的版本。因此,如果您已经在使用它,则无需担心跳转到不稳定的 1.2。但是 1.1.5 和 1.2 之间存在相当多的差异,因此我还没有采取行动。

标签: angularjs twitter-bootstrap-3 angularjs-ng-repeat


【解决方案1】:

如果您正在使用 Bootstrap 3 和 AngularJS,您可以声明一个新过滤器,该过滤器将返回一个子数组切片数组,然后执行两次 ng-repeat。

看起来像这样:

  <div class="row" ng-repeat="row in filtered = (arr | splitArrayFilter:3)">
        <div class="col-md-4" ng-repeat="n in row">
          <h3>{{n}}</h3>
        </div>
  </div>
app.filter('splitArrayFilter', function() {
  return function(arr, lengthofsublist) {
    if (!angular.isUndefined(arr) && arr.length > 0) {
      var arrayToReturn = [];  
      var subArray=[]; 
      var pushed=true;      
      for (var i=0; i<arr.length; i++){
        if ((i+1)%lengthofsublist==0) {
          subArray.push(arr[i]);
          arrayToReturn.push(subArray);
          subArray=[];
          pushed=true;
        } else {
          subArray.push(arr[i]);
          pushed=false;
        }
      }
      if (!pushed)
        arrayToReturn.push(subArray);

      console.log(JSON.stringify(arrayToReturn));
      return arrayToReturn; 
    }
  }
}); 

您可以在 Plunker 上找到它:http://plnkr.co/edit/rdyjRtZhzHjWiWDJ8FKJ?p=preview 由于某种原因,plunker 中的视图不支持 bootstrap 3 列,但如果您在嵌入式视图或浏览器中打开它,您可以看到它可以工作。

【讨论】:

  • 这太棒了,谢谢分享。将在我当前的项目中使用!
  • 给我错误:“未捕获的错误:[$rootScope:infdig] 10 $digest() 达到了迭代。中止!”
  • 我不想滚动自己的过滤器,只需将 angular-filter 添加到您的项目并使用 chunkBy。 github.com/a8m/angular-filter#chunkby 在控制器中进行过滤,并在嵌套的 ng-repeat 中使用 track by 并使用适当的键。
  • 我在控制器中使用了过滤器而不是没有角度过滤器插件的视图,因此我摆脱了无限的 $digest。谢谢
【解决方案2】:

你用ng-class 做的事情很聪明。我从来没有想过在表达式中使用%2

但为了将来参考,有一种更简单的方法可以做到这一点:ng-class-evenng-class-odd。它和你做的一样,但更干净一点:

<div ng-repeat="num in numbers" ng-class-even="'md-col-6'" ng-class-odd="'row'">
    {{num}}
</div>

但这并不能解决您的问题。如果我理解正确,您需要一行,该行中有两列。我能想到的最简单的方法是拆分数组。将重复放在div 上,然后在div 中有2 个span。我认为您最初遇到的问题之一是您重复单个 div,并试图将 block 元素视为 inline

控制器

myApp.controller('MyCtrl', function ($scope) {
    $scope.evens = ["2","4","6","8","10","12","14"];
    $scope.odds = ["1","3","5","7","9","11","13"];
});

HTML

<div ng-controller="MyCtrl">
    <div ng-repeat="odd in odds" class="row">
        <span class="span3">{{odd}}</span>
        <span class="span2">{{evens[$index]}}</span>
    </div>
</div>

Fiddle

由于您使用的是 1.1.5 版,这也为您打开了一条新指令:ng-if!你也可以使用ng-switch做一些条件逻辑展示。

您的小提琴中没有包含引导程序,由于某种原因,我无法让 jsFiddle 显示引导程序。所以我创建了一些类似于引导程序的临时 CSS 类class="span"

【讨论】:

  • +1 我知道奇数和偶数必须有一些东西,谢谢。无论我想水平重复多少元素(达到框架限制(通常为 12 个)),我都希望能找到一些有用的东西,以备将来使用。在这种情况下,奇数甚至偶数都不起作用,但是对于我的应用程序来说,这是一个可靠的解决方案。我会接受你的回答,再次感谢。
【解决方案3】:

不需要添加 .row 类..我这样做了:

HTML:

<div ng-repeat="product in allProducts">
  <div class="my-col-50">
    <h1>{{product.title}}</h1>
  </div>
</div>

CSS:

.my-col-50{float:left;width:50%;}

它的工作就像一个魅力。

【讨论】:

  • 这不适用于高度不均匀的列,这与行布局有关
【解决方案4】:

虽然这不是“正确”的做法,但有一种方法可以使用 CSS 来实现。

例如,这是一个 3 列布局:

HTML:

<div class="row">
    <div ng-repeat="(key, pod) in stats.pods" class="pod-wrap">
        <div ng-if="objectCheck(pod) == false" class="col-md-4 col-sm-4 pod">
            <div>
                <h2 ng-bind="key"></h2>
                <p class="total" ng-bind="pod | number"></p>
            </div>
        </div>

        <div ng-if="objectCheck(pod) == true" class="col-md-4 col-sm-4 pod">
            <div>
                <h2 ng-bind="key"></h2>

                <div ng-repeat="(type, value) in pod track by $index">
                    <p class="status"><% type %> <small><% value %></small></p>
                </div>
            </div>
        </div>
    </div>
</div>

CSS:

.pod-wrap:nth-of-type(3n):after {
    display: table;
    content: '';
    clear: both;
}

【讨论】:

    【解决方案5】:

    我尝试了这里给出的两个建议... yshaool 的作品很好,但就像我评论它给了我无限循环错误。

    然后我尝试了类似下面的方法:

    <div class="row" ng-repeat="row in split($index, 3, row.Attempts)">
          <div class="col-md-4" ng-repeat="attempt in row">
              <div>Attempt {{row.AttemptNumber}}</div>
              <div>{{row.Result}}</div>
          </div>              
    </div>
    

    和功能:

    $scope.split = function (index, length, attempts) {
    
           var ret = attempts.slice(index * length, (index * length) + length);
           console.log(JSON.stringify(ret));
           return ret;
    
    }
    

    当我意识到它可以像

    <div ng-repeat="attempt in row.Attempts">
          <div class="col-md-4">
              <div>Attempt {{attempt.AttemptNumber}}</div>
              <div>{{attempt.Result}}</div>
         </div>                    
    </div>
    

    使用 "col-md-4" 可以解决问题,因为我只需要每行使用三列进行拆分.. (让引导程序完成工作!) 无论如何,这里的其他答案真的很有用......

    【讨论】:

    • 仅当您的列高相等时,让引导程序包裹列才有效。如果列高不相等,则换行会中断,结果很丑。
    【解决方案6】:

    根据模板中所需的列数,在控制器中创建原始数据源的块。

    $scope.categories = data //contains your original data source;
    $scope.chunkedCategories = [] //will push chunked data into this;
    //dividing into chunks of 3 for col-4. You can change this
    while ($scope.categories.length > 0)
     $scope.chunkedCategories.push($scope.categories.splice(0, 3));
    

    在您的模板中,您现在可以执行以下操作

    <div class="row" ng-repeat="categories in chunkedCategories">
     <div class="col-xs-4" ng-repeat="category in categories">
      <h2>{{category.title}}</h2>
     </div>         
    </div>  
    

    【讨论】:

      【解决方案7】:

      我的方法是使用 $index 变量,该变量由 AngularJS 在 ng-repeat 指令中创建和更新,以触发对 CSS clearfix hack 的调用,这反过来又重置到新行。

      我正在使用以下版本:AngularJS 1.5.5 和 Bootstrap 3.3.4

      <!-- use bootstrap's grid structure to create a row -->
      <div class="row">
      
          <!-- Cycle through a list: -->
          <!-- use angular's ng-repeat directive -->
          <div ng-repeat="item in itemList">
      
              <!-- Start a new row: -->
              <!-- use the css clearfix hack to reset the row -->
              <!-- for every item $index divisible by 3. -->
              <!-- note that $index starts at 0. -->
              <div ng-if="$index % 3 == 0" class="clearfix"></div>
      
              <!-- Create a column: -->
              <!-- since we want 3 "item columns"/row, -->
              <!-- each "item column" corresponds to 4 "Bootstrap columns" -->
              <!-- in Bootstrap's 12-column/row system -->
              <div class="col-sm-4">
                  {{item.name}}
              </div>
          </div>
      </div>
      

      【讨论】:

        【解决方案8】:

        为了保持解决方案引导程序的格式,我使用 ng-class 解决了这个问题

        <div ng-repeat="item in items">
            <div ng-class="{ 'row': ($index + 1) % 4 == 0 }">
                <div class="col-md-3">
                    {{item.name}}
                </div>
            </div>
        </div>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-11-30
          • 2013-08-11
          • 1970-01-01
          • 2015-12-02
          • 2016-12-26
          • 2016-07-11
          • 2016-07-10
          • 1970-01-01
          相关资源
          最近更新 更多