Горизонтальный ng-repeat (er) с новыми разрывами строк

Работа с Bootstrap и AngularJS, есть ли способ ng-repeat по горизонтали с новой строкой для каждого заданного количества элементов?

Я играл с ng-class, чтобы выполнить этот Fiddle, но проблема в том, что я не могу получить float left divs внутри начального 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;
}

Ответ 1

Было хорошо, что вы делали с ng-class. Я никогда не думал использовать %2 внутри выражения.

Но для дальнейшего использования есть несколько более простой способ: ng-class-even и ng-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-классов temp, которые несколько напоминали бы загрузочные файлы class="span"

Ответ 2

Если вы работаете с 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 не поддерживает бутстрап 3 столбца, но если вы откроете его во встроенном представлении или в браузерах, вы увидите, что он работает.

Ответ 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.

Например, это для компоновки из трех столбцов:

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, который, в свою очередь, сбрасывается в новую строку.

Я использую следующие версии: AngularJS 1.5.5 и Bootstrap 3.3.4

<!-- use bootstrap grid structure to create a row -->
<div class="row">

    <!-- Cycle through a list: -->
    <!-- use angular 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 12-column/row system -->
        <div class="col-sm-4">
            {{item.name}}
        </div>
    </div>
</div>

Ответ 8

Чтобы сохранить решение bootstrap, я решил это, используя 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>