Массив Ng-Repeat для строк и столбцов

Спасибо, что нашли время, чтобы прочитать это, мне было интересно, как я могу использовать ng-repeat, чтобы создать сетку, такую ​​как box of options. Я бы хотел, чтобы массив повторял n-е число элементов, а затем переходил к следующей строке или столбцу, пока не будут перечислены все элементы. например.

Предполагая, что у меня есть массив вроде [opt1,opt2,opt3,opt4,opt5,opt6,opt7], я хотел бы отображать его следующим образом:

opt1 opt2 opt3
opt4 opt5 opt6
opt7

Ответы

Ответ 1

Это больше проблема стиля или разметки, чем у AngularJS. Если вы действительно этого хотите, вы можете сделать:

<span ng:repeat="(index, value) in array">
    {{value}}<br ng:show="(index+1)%3==0" />
</span>

http://jsfiddle.net/JG3A5/

Ответ 2

Извините за мои HAML и Bootstrap3:

.row
  .col-lg-4
    %div{'ng:repeat' => "item in array.slice(0, array.length / 3)"}
      {{item}}
  .col-lg-4
    %div{'ng:repeat' => "item in array.slice(array.length / 3, array.length * 2/3)"}
      {{item}}
  .col-lg-4
    %div{'ng:repeat' => "item in array.slice(array.length * 2/3, array.length)"}
      {{item}}

Существует другая версия, с возможностью использования фильтров:

<div class="row">
  <div class="col-md-4" ng-repeat="remainder in [0,1,2]">
    <span ng-repeat="item in array" ng-if="$index % 3 == remainder">{{item}}</span>
  </div>
</div>

Ответ 3

Если все ваши элементы находятся в одном массиве, лучше всего сделать сетку в CSS. Эта статья должна быть полезной: http://css-tricks.com/dont-overthink-it-grids/

Вы можете использовать $index из ng-repeat, чтобы применить правильный класс для вашего столбца (в этом случае 4 столбца):

<div class="col-{{ $index % 4 }}"></div>

Если у вас есть 2-мерный массив (разделенный на строки и столбцы), который открывает больше возможностей, например, с использованием таблицы HTML.

Ответ 4

Мне проще просто использовать ng-repeat в сочетании с ng-if и компенсировать любые индексы с помощью $index. Обратите внимание на нефрит ниже:

div(ng-repeat="product in products")
    div.row(ng-if="$index % 2 === 0")
      div.col(ng-init="p1 = products[$index]")
          span p1.Title
      div.col(ng-if="products.length > $index + 1", ng-init="p2 = products[$index + 1]")
          span p2.Title
      div.col(ng-if="products.length <= $index + 1")

Ответ 5

Между производительностью, динамикой и удобочитаемостью

Кажется, что логика в вашем JavaScript - лучший метод. Я бы просто укусил пулю и посмотрел:

function listToMatrix(list, n) {
    var grid = [], i = 0, x = list.length, col, row = -1;
    for (var i = 0; i < x; i++) {
        col = i % n;
        if (col === 0) {
            grid[++row] = [];
        }
        grid[row][col] = list[i];
    }
    return grid;
}

var matrix = listToMatrix(lists, 3);
console.log('#RedPill', matrix);
  • @Params: (list, n)
    • Где список - любой массив, а n - произвольное количество столбцов, требуемое для каждой строки
  • @Возвращение: матроид
  • @Примечание. Эта функция предназначена для ориентации матроида на основе произвольного количества столбцов с разницей в количестве строк. Другими словами, x = искомые столбцы, y = n.

Затем вы можете создать angular filter для этого:

Фильтр:

angular.module('lists', []).filter('matrical', function() {
    return function(list, columns) {
        return listToMatrix(list, columns);
    };
});

Контроллер:

function listOfListsController($scope) {
    $scope.lists = $http.get('/lists');
}

Вид:

<div class="row" ng-repeat="row in (lists | matrical:3)">
    <div class="col col-33" ng-repeat="list in row">{{list.name}}</div>
</div>

С этим вы можете видеть, что вы получаете n количество строк - каждый из которых содержит столбцы 3. Когда вы меняете количество нужных столбцов, вы заметите, что количество строк изменяется соответствующим образом (при условии, что длина списка всегда одна и та же;)).

Здесь fiddle.

Обратите внимание, что вы получаете ol 'Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!. Это связано с тем, что angular вызывает функцию matrical на каждой итерации. Предположительно, вы можете использовать псевдоним as results, чтобы предотвратить angular от переоценки коллекции, но мне не повезло. Для этого лучше фильтровать сетку внутри вашего контроллера и использовать это значение для вашего ретранслятора: $filter('matrical')(items) - , но, пожалуйста, отправьте сообщение, если вы встретите элегантный способ его фильтрации в ng-repeat.

Я бы еще раз подчеркнул, что вы, вероятно, идете по темному переулку, пытаясь написать логику на ваш взгляд, но я рекомендую вам попробовать ее, если вы этого еще не сделали.

Изменить

Использование этого алгоритма должно сочетаться с Matrical Data-Structure, чтобы предоставить методы push, pop, splice, а дополнительные методы - в сочетании с соответствующей логикой для дополнения Двунаправленного привязки данных, если это необходимо. Другими словами, привязка данных не будет работать из коробки (конечно), как при добавлении нового элемента в ваш список, необходимо провести переоценку всего списка, чтобы сохранить структурную целостность матрицы.

Предложение: Используйте синтаксис $filter('matrical')($scope.list) в сочетании с $scope.$watch и перекомпилируйте/вычислите позиции позиции для матрицы.

Ура!