comment diviser les données ng-repeat avec trois colonnes à l'aide de bootstrap

122

J'utilise ng-repeat avec mon code J'ai un nombre 'n' de zone de texte basé sur ng-repeat. Je souhaite aligner la zone de texte sur trois colonnes.

c'est mon code

<div class="control-group" ng-repeat="oneExt in configAddr.ext">
    {{$index+1}}. 
    <input type="text" name="macAdr{{$index+1}}" 
           id="macAddress" ng-model="oneExt.newValue" value=""/>
</div>
kuppu
la source
1
alors en supposant que vous avez neuf (9) que vous voulez 1,2,3 dans une ligne ou dans une colonne?
Gabriele Petrioli

Réponses:

254

L'approche la plus fiable et la plus techniquement correcte consiste à transformer les données dans le contrôleur. Voici une simple fonction et utilisation de bloc.

function chunk(arr, size) {
  var newArr = [];
  for (var i=0; i<arr.length; i+=size) {
    newArr.push(arr.slice(i, i+size));
  }
  return newArr;
}

$scope.chunkedData = chunk(myData, 3);

Ensuite, votre vue ressemblerait à ceci:

<div class="row" ng-repeat="rows in chunkedData">
  <div class="span4" ng-repeat="item in rows">{{item}}</div>
</div>

Si vous avez des entrées dans le ng-repeat, vous voudrez probablement décoller / rejoindre les tableaux lorsque les données sont modifiées ou lors de la soumission. Voici à quoi cela ressemblerait dans un $watch, de sorte que les données soient toujours disponibles dans le format d'origine fusionné:

$scope.$watch('chunkedData', function(val) {
  $scope.data = [].concat.apply([], val);
}, true); // deep watch

Beaucoup de gens préfèrent accomplir cela dans la vue avec un filtre. Ceci est possible, mais ne doit être utilisé qu'à des fins d'affichage! Si vous ajoutez des entrées dans cette vue filtrée, cela causera des problèmes qui peuvent être résolus, mais qui ne sont ni jolis ni fiables .

Le problème avec ce filtre est qu'il renvoie à chaque fois de nouveaux tableaux imbriqués. Angular surveille la valeur de retour du filtre. La première fois que le filtre s'exécute, Angular connaît la valeur, puis l'exécute à nouveau pour s'assurer qu'elle a bien été modifiée. Si les deux valeurs sont identiques, le cycle est terminé. Sinon, le filtre se déclenchera encore et encore jusqu'à ce qu'ils soient identiques, ou Angular se rend compte qu'une boucle de digestion infinie se produit et s'arrête. Étant donné que les nouveaux tableaux / objets imbriqués n'étaient pas précédemment suivis par Angular, il voit toujours la valeur de retour comme différente de la précédente. Pour corriger ces filtres "instables", vous devez envelopper le filtre dans une memoizefonction. lodasha une memoizefonction et la dernière version de lodash comprend également une chunkfonction, nous pouvons donc créer ce filtre très simplement en utilisantnpmmodules et compiler le script avec browserifyou webpack.

N'oubliez pas: affichage uniquement! Filtrez dans le contrôleur si vous utilisez des entrées!

Installez lodash:

npm install lodash-node

Créez le filtre:

var chunk = require('lodash-node/modern/array/chunk');
var memoize = require('lodash-node/modern/function/memoize');

angular.module('myModule', [])
.filter('chunk', function() {
  return memoize(chunk);
});

Et voici un exemple avec ce filtre:

<div ng-repeat="row in ['a','b','c','d','e','f'] | chunk:3">
  <div class="column" ng-repeat="item in row">
    {{($parent.$index*row.length)+$index+1}}. {{item}}
  </div>
</div>

Commander les articles verticalement

1  4
2  5
3  6

Concernant les colonnes verticales (liste de haut en bas) plutôt qu'horizontales (de gauche à droite), l'implémentation exacte dépend de la sémantique souhaitée. Les listes qui se divisent de manière inégale peuvent être distribuées de différentes manières. Voici une façon:

<div ng-repeat="row in columns">
  <div class="column" ng-repeat="item in row">
    {{item}}
  </div>
</div>
var data = ['a','b','c','d','e','f','g'];
$scope.columns = columnize(data, 3);
function columnize(input, cols) {
  var arr = [];
  for(i = 0; i < input.length; i++) {
    var colIdx = i % cols;
    arr[colIdx] = arr[colIdx] || [];
    arr[colIdx].push(input[i]);
  }
  return arr;
}

Cependant, le moyen le plus direct et le plus simple d'obtenir des colonnes est d'utiliser des colonnes CSS :

.columns {
  columns: 3;
}
<div class="columns">
  <div ng-repeat="item in ['a','b','c','d','e','f','g']">
    {{item}}
  </div>
</div>
m59
la source
Merci de votre aide. Mais l'utilisation du carrousel avec ui-chart en angulaire ne peut pas dessiner le graphique bt carousel fonctionne bien. mon code est <carousel interval = "myInterval"> <slide ng-repeat = "milestone in mileStone | split: 4" active = "slide.active"> <div class = "col-md-3" ng-repeat = " milestone1 in milestone "> <div style =" text-align: center; "> <div ui-chart =" data "chart-options =" ​​chartOptions "> </div> </div> </div> </ slide > </carousel> Et j'ai initialisé ma variable de portée en tant que données JSON jalon.
kuppu
1
@ m59 À l'heure actuelle, cette fonction affiche les données dans la première ligne, a b cdeuxième ligne d e f. Puis-je afficher a b dans la première colonne c dde la deuxième colonne et e fdans la troisième colonne? Merci
1
@ Ifch0o1 Vous auriez raison si c'était le cas [].concat.call([], val). Vous devez considérer ce que applyfait. valest un tableau de tableaux, et nous voulons passer chacun de ces tableaux à l'intérieur comme arguments à concat. Je pense que vous vous concentrez sur le contexte de [], ce qui n'est pas le but ici. Ce que nous voulons [].concat(val[1], val[2], val[3], etc), c'est donc nous avons besoinapply([], val)
m59
1
@bahadir J'ai mis à jour la réponse pour être plus claire. Découvrez ce qui se passe si vous créez un filtre qui renvoie simplement []vs [[]]et [{}]. Le tableau / objet imbriqué permet à Angular de voir un résultat différent sur chaque filter, et continue de répéter à la recherche du résultat pour rester le même (stabiliser).
m59
1
Vous spammez vraiment les commentaires :) Essayez-le par vous-même. var x = [1,2,3]; var y = [1,2,3]; console.log(x === y);La vérification approfondie signifie soit la stringification et la comparaison de chaînes, ce qui est risqué car un objet peut ne pas être stringifiable, soit la vérification récursive de chaque propriété individuellement. Je pense qu'Angular pourrait implémenter cela pour les filtres, mais je suis sûr qu'il y a une bonne raison pour laquelle ils ne l'ont pas fait. Probablement parce qu'ils visaient principalement des filtres pour une simple modification d'un ensemble de données, et non une refonte complète avec des modifications de la structure.
m59
64

Cette solution est très simple:

JSON:

[{id:"1",name:"testA"},{id:"2",name:"test B"},{id:"3",name:"test C"},{id:"4",name:"test D"},{id:"5",name:"test E"}]

HTML:

<div ng-controller="MyCtrl">
  <table>
    <tr ng-repeat="item in items" ng-switch on="$index % 3">
      <td ng-switch-when="0">
        {{items[$index].id}} {{items[$index].name}}
      </td>
      <td ng-switch-when="0">
        <span ng-show="items[$index+1]">
          {{items[$index+1].id}} {{items[$index+1].name}}
        </span>
      </td>
      <td ng-switch-when="0">
        <span ng-show="items[$index+2]">    
          {{items[$index+2].id}} {{items[$index+2].name}}
        </span>
      </td>
    </tr>
  </table>
</div>

DEMO dans FIDDLE

entrez la description de l'image ici

Stéphane GRILLON
la source
3
Meilleure réponse! Et faites ce dont vous avez besoin avec les directives natives! Félicitations!
Renan Franca
1
Cette solution fonctionne, mais en ce qui concerne les meilleures pratiques, vous ne devriez probablement pas utiliser de tableaux pour définir la mise en page dans votre balisage :)
Dave Cooper
2
Comme le mentionne @DaveCooper, voici une disposition alternative sans tableaux: plnkr.co/edit/81oj8mHaNyfQpCmRBWO4?p=preview . Considérez les tableaux pour les données tabulées, mais sinon, c'est une meilleure mise en page pour les appareils mobiles et les tailles d'écran variables.
Zymotik
1
C'est de loin la meilleure solution. Il faut du temps pour trouver toutes les bizarreries lors de l'utilisation d'un nouveau framework, mais ng-switch est une aubaine
Zoran
Si vous optez pour des div au lieu d'une table, vous pouvez placer ng-switch-when="0"une fois sur un div externe au lieu de sur les 3 éléments.
Hans Wouters
19

Une solution propre et adaptable qui ne nécessite pas de manipulation de données :

Le HTML:

<div class="control-group" class="label"
    ng-repeat="oneExt in configAddr.ext"
    ng-class="{'new-row': startNewRow($index, columnBreak) }">
    {{$index+1}}. 
    <input type="text" name="macAdr{{$index+1}}" 
       id="macAddress{{$index}}" ng-model="oneExt.newValue" />
</div>

Le CSS:

.label {
    float: left;
    text-align: left;
}
.new-row {
    clear: left;
}

Le JavaScript:

$scope.columnBreak = 3; //Max number of colunms
$scope.startNewRow = function (index, count) {
    return ((index) % count) === 0;
};

Il s'agit d'une solution simple pour rendre les données en lignes et en colonnes de manière dynamique sans avoir à manipuler le tableau de données que vous essayez d'afficher. De plus, si vous essayez de redimensionner la fenêtre du navigateur, vous pouvez voir que la grille s'adapte dynamiquement à la taille de l'écran / div.

(J'ai également ajouté un suffixe {{$ index}} à votre identifiant car ng-repeat essaiera de créer plusieurs éléments avec le même identifiant si vous ne le faites pas.)

Un exemple de travail similaire

Cumulo Nimbus
la source
1
Je pense que l'OP voulait le balisage pour les lignes / colonnes Twitter Bootstrap, mais cela peut être utile à quelqu'un. Cependant, vous devez mettre le code et l'explication dans votre réponse. Les réponses aux liens uniquement seront supprimées.
m59
@ m59 Réponse mise à jour. Merci pour la suggestion
Cumulo Nimbus
1
Big +1 pour ne nécessite pas de manipulation de données . Cela a parfaitement fonctionné pour mes besoins de séparation des données dans un intervalle en utilisant ng-repeat en 2 colonnes afin que mon modal Bootstrap ne soit pas si long! J'ai été surpris de voir à quel point c'était simple à mettre en œuvre! <span ng-repeat="z in waiverModalLinks" ng-class="{'new-row':startNewRow($index, columnBreak)}" class="{{z.id}}"><a href="{{z.link}}{{z.title}}">{{z.title}}</a></span>C'est à l'intérieur de `modal-body '.
Christine268
15

La réponse de m59 est plutôt bonne. La seule chose que je n'aime pas, c'est qu'il utilise divs pour ce qui pourrait être des données pour une table.

Donc, en conjonction avec le filtre de m59 (réponse quelque part ci-dessus), voici comment l'afficher dans un tableau.

<table>
    <tr class="" ng-repeat="rows in foos | chunk:2">
        <td ng-repeat="item in rows">{{item}}</td>
    </tr>
</table>
Jarrod
la source
7

Voici un moyen plus simple:

<table>
    <tr ng-repeat="item in lists" ng-hide="$index%2!==0">
        <td>
            <label>{{ lists[$index].name}}</label>
        </td>
        <td ng-hide="!lists[$index+1]">
            <label>{{ lists[$index+1].name}}</label>
        </td>
    </tr>
</table>

La réponse de Cumulo Nimbus m'est utile mais je veux que cette grille soit entourée d'un div qui peut afficher la barre de défilement lorsque la liste est trop longue.

Pour ce faire, j'ai ajouté style="height:200px; overflow:auto"à un div autour de la table, ce qui l'affiche sous forme de colonne unique.

Fonctionne maintenant pour une longueur de tableau de un.

obtenir
la source
lorsqu'il n'y a qu'un seul élément dans le tableau, il n'afficherait pas la première ligne elle-même. pour corriger ce changement le ng-hide="$index%2!==0"
Anuj Pandey
4

J'ai une fonction et je l'ai stockée dans un service afin de pouvoir l'utiliser partout dans mon application:

Un service:

app.service('SplitArrayService', function () {
return {
    SplitArray: function (array, columns) {
        if (array.length <= columns) {
            return [array];
        };

        var rowsNum = Math.ceil(array.length / columns);

        var rowsArray = new Array(rowsNum);

        for (var i = 0; i < rowsNum; i++) {
            var columnsArray = new Array(columns);
            for (j = 0; j < columns; j++) {
                var index = i * columns + j;

                if (index < array.length) {
                    columnsArray[j] = array[index];
                } else {
                    break;
                }
            }
            rowsArray[i] = columnsArray;
        }
        return rowsArray;
    }
}

});

Manette:

$scope.rows   = SplitArrayService.SplitArray($scope.images, 3); //im splitting an array of images into 3 columns

Balisage:

 <div class="col-sm-12" ng-repeat="row in imageRows">
     <div class="col-sm-4" ng-repeat="image in row">
         <img class="img-responsive" ng-src="{{image.src}}">
     </div>
 </div>
Chancho
la source
Bien que ce soit cool, cela n'aide pas lorsque vous utilisez les autres filtres tels que orderBy ou filter.
Robbie Smith
2

Mon approche était un mélange de choses.

Mon objectif était d'avoir une grille s'adaptant à la taille de l'écran. Je voulais 3 colonnes pour lg, 2 colonnes pour smet mdet 1 colonne pour xs.

Tout d'abord, j'ai créé la fonction d'étendue suivante, en utilisant le $windowservice angulaire :

$scope.findColNumberPerRow = function() {
    var nCols;
    var width = $window.innerWidth;

    if (width < 768) {
        // xs
        nCols = 1;
    }
    else if(width >= 768 && width < 1200) {
         // sm and md
         nCols = 2
    } else if (width >= 1200) {
        // lg
        nCols = 3;
    }
    return nCols;
};

Ensuite, j'ai utilisé la classe proposée par @Cumulo Nimbus:

.new-row {
    clear: left;
}

Dans le div contenant le ng-repeat, j'ai ajouté la resizabledirective, comme expliqué dans cette page , de sorte qu'à chaque fois que la fenêtre est redimensionnée, le $windowservice angulaire est mis à jour avec les nouvelles valeurs.

En fin de compte, dans le div répété, j'ai:

ng-repeat="user in users" ng-class="{'new-row': ($index % findColNumberPerRow() === 0) }"

S'il vous plaît, faites-moi savoir les défauts de cette approche.

J'espère que cela peut être utile.

igorauad
la source
2

Une astuce simple avec le CSS "clearfix" recommandé par Bootstrap:

<div class="row">
      <div ng-repeat-start="value in values" class="col-md-4">
        {{value}}
      </div>
      <div ng-repeat-end ng-if="$index % 3 == 0" class="clearfix"></div>
</div>

De nombreux avantages: efficace, rapide, utilisant les recommandations Boostrap, évitant les éventuels problèmes de $ digest et ne modifiant pas le modèle angulaire.

Lastnico
la source
1

Cet exemple produit un répéteur imbriqué où les données externes incluent un tableau interne que je voulais répertorier dans deux colonnes. Le concept serait vrai pour trois colonnes ou plus.

Dans la colonne intérieure, je répète la «ligne» jusqu'à ce que la limite soit atteinte. La limite est déterminée en divisant la longueur du tableau d'éléments par le nombre de colonnes souhaité, dans ce cas par deux. La méthode de division se trouve sur le contrôleur et reçoit la longueur actuelle du tableau en tant que paramètre. La fonction de tranche JavaScript (0, array.length / columnCount) a ensuite appliqué la limite au répéteur.

Le deuxième répéteur de colonne est alors appelé et répète la tranche (array.length / columnCount, array.length) qui produit la seconde moitié du tableau dans la deuxième colonne.

<div class="row" ng-repeat="GroupAccess in UsersController.SelectedUser.Access" ng-class="{even: $even, odd: $odd}">
    <div class="col-md-12 col-xs-12" style=" padding-left:15px;">
        <label style="margin-bottom:2px;"><input type="checkbox" ng-model="GroupAccess.isset" />{{GroupAccess.groupname}}</label>
    </div>
    <div class="row" style=" padding-left:15px;">
        <div class="col-md-1 col-xs-0"></div>
        <div class="col-md-3 col-xs-2">
            <div style="line-height:11px; margin-left:2px; margin-bottom:2px;" ng-repeat="Feature in GroupAccess.features.slice(0, state.DivideBy2(GroupAccess.features.length))">
                <span class="GrpFeature">{{Feature.featurename}}</span>
            </div>
        </div>
        <div class="col-md-3 col-xs-2">
            <div style="line-height:11px; margin-left:2px; margin-bottom:2px;" ng-repeat="Feature in GroupAccess.features.slice( state.DivideBy2(GroupAccess.features.length), GroupAccess.features.length )">
                <span class="GrpFeature">{{Feature.featurename}}</span>
            </div>
        </div>
        <div class="col-md-5 col-xs-8">
        </div>
    </div>
</div>


// called to format two columns
state.DivideBy2 = function(nValue) {
    return Math.ceil(nValue /2);
};

J'espère que cela aidera à regarder la solution d'une autre manière encore. (PS c'est mon premier message ici! :-))

Harvey Mushman
la source
1

Je répare sans .row

<div class="col col-33 left" ng-repeat="photo in photos">
   Content here...
</div>

et css

.left {
  float: left;
}
selahattinunlu
la source
1

Voici une façon facile de le faire. C'est plus manuel et se termine par un balisage désordonné. Je ne le recommande pas, mais dans certaines situations, cela pourrait être utile.

Voici un lien de violon http://jsfiddle.net/m0nk3y/9wcbpydq/

HTML:

<div ng-controller="myController">
    <div class="row">
        <div class="col-sm-4">
            <div class="well">
                <div ng-repeat="person in people = data | limitTo:Math.ceil(data.length/3)">
                {{ person.name }}
                </div>
            </div>
        </div>
        <div class="col-sm-4">
            <div class="well">
                <div ng-repeat="person in people = data | limitTo:Math.ceil(data.length/3):Math.ceil(data.length/3)">
                {{ person.name }}
                </div>
            </div>
        </div>
        <div class="col-sm-4">
            <div class="well">
                <div ng-repeat="person in people = data | limitTo:Math.ceil(data.length/3):Math.ceil(data.length/3)*2">
                {{ person.name }}
                </div>
            </div>
        </div>
    </div>
</div>

JS:

var app = angular.module('myApp', []);

app.controller('myController', function($scope) {

    $scope.Math = Math;
    $scope.data = [
        {"name":"Person A"},
        ...
    ];
});

Cette configuration nous oblige à utiliser des Maths sur le balisage: /, vous devrez donc injecter Math en ajoutant cette ligne: $scope.Math = Math;

Gene Parcellano
la source
1

Toutes ces réponses semblent massivement surfaites.

La méthode de loin la plus simple serait de configurer les div d'entrée dans un bootstrap de colonne col-md-4, puis bootstrap le formatera automatiquement en 3 colonnes en raison de la nature de 12 colonnes du bootstrap:

<div class="col-md-12">
    <div class="control-group" ng-repeat="oneExt in configAddr.ext">
        <div class="col-md-4">
            <input type="text" name="macAdr{{$index}}"
                   id="macAddress" ng-model="oneExt.newValue" value="" />
        </div>
    </div>
</div>
cullimorer
la source
1
<div class="row">
  <div class="col-md-4" ng-repeat="remainder in [0,1,2]">
    <ul>
      <li ng-repeat="item in items" ng-if="$index % 3 == remainder">{{item}}</li>
    </ul>
  </div>
</div>
mrded
la source
0

Sur la base de la très bonne réponse de m59. J'ai trouvé que les entrées de modèle seraient floues si elles changeaient, donc vous ne pouviez changer qu'un caractère à la fois. Ceci est un nouveau pour les listes d'objets pour tous ceux qui en ont besoin:

MODIFIER Mise à jour pour gérer plusieurs filtres sur une seule page

app.filter('partition', function() {
  var cache = {}; // holds old arrays for difference repeat scopes
  var filter = function(newArr, size, scope) {
    var i,
      oldLength = 0,
      newLength = 0,
      arr = [],
      id = scope.$id,
      currentArr = cache[id];
    if (!newArr) return;

    if (currentArr) {
      for (i = 0; i < currentArr.length; i++) {
        oldLength += currentArr[i].length;
      }
    }
    if (newArr.length == oldLength) {
      return currentArr; // so we keep the old object and prevent rebuild (it blurs inputs)
    } else {
      for (i = 0; i < newArr.length; i += size) {
        arr.push(newArr.slice(i, i + size));
      }
      cache[id] = arr;
      return arr;
    }
  };
  return filter;
}); 

Et ce serait l'utilisation:

<div ng-repeat="row in items | partition:3:this">
  <span class="span4">
    {{ $index }}
  </span>
</div>
JSous
la source
Pour autant que je sache, cela devrait fonctionner la plupart du temps, mais cette logique de mise en cache ne semble pas entièrement fiable et passer dans la portée est maladroit. Je recommande vraiment de filtrer simplement dans le contrôleur lorsque des entrées sont nécessaires. C'est de toute façon l'approche techniquement correcte.
m59
0

Je suis nouveau dans bootstrap et angularjs, mais cela pourrait également faire Array par 4 éléments en un seul groupe, le résultat ressemblera presque à 3 colonnes. Cette astuce utilise le principe de la ligne de rupture bootstrap.

<div class="row">
 <div class="col-sm-4" data-ng-repeat="item in items">
  <div class="some-special-class">
   {{item.XX}}
  </div>
 </div>
</div>
Nathan
la source
0

Lodash a maintenant une méthode chunk intégrée que j'utilise personnellement: https://lodash.com/docs#chunk

Sur cette base, le code du contrôleur peut ressembler à ce qui suit:

$scope.groupedUsers = _.chunk( $scope.users, 3 )

Afficher le code:

<div class="row" ng-repeat="rows in groupedUsers">
  <div class="span4" ng-repeat="item in rows">{{item}}</div>
</div>
sean2078
la source
0

Une autre méthode consiste à définir width:33.33%; float:leftun div wrapper comme celui-ci:

<div ng-repeat="right in rights" style="width: 33.33%;float: left;">
    <span style="width:60px;display:inline-block;text-align:right">{{$index}}</span>
    <input type="number" style="width:50px;display:inline-block" ">
</div>
obtenir
la source
0

Je me suis retrouvé dans un cas similaire, souhaitant générer des groupes d'affichage de 3 colonnes chacun. Cependant, bien que j'utilisais bootstrap, j'essayais de séparer ces groupes en différentes div parentales. Je voulais aussi créer quelque chose d'utile de manière générique.

Je l'ai approché avec 2 ng-repeatcomme ci-dessous:

<div ng-repeat="items in quotes" ng-if="!($index % 3)">
  <div ng-repeat="quote in quotes" ng-if="$index <= $parent.$index + 2 && $index >= $parent.$index">
                ... some content ...
  </div>
</div>

Cela rend très facile de passer à un nombre différent de colonnes et de les séparer en plusieurs div parent.

Matt Kindy
la source
0

Juste au cas où quelqu'un voudrait un Angular 7 (et une version supérieure), voici un exemple que j'ai utilisé dans l'une de mes applications:

HTML:

                   <div class="container-fluid">
                    <div class="row" *ngFor="let reports of chunkData; index as i">
                        <div *ngFor="let report of reports" class="col-4 col-sm-4"
                            style="border-style:solid;background-color: antiquewhite">{{report}}</div>
                    </div>
                </div>

FICHIER .TS

export class ConfirmationPageComponent implements OnInit {
  chunkData = [];
  reportsArray = ["item 1", "item 2", "item 3", "item 4", "item 5", "item 6"];
  
  constructor() {}

  ngOnInit() {
    this.chunkData = this.chunk(this.reportsArray, 3);
  }

  chunk(arr, size) {
    var newArr = [];
    for (var i = 0; i < arr.length; i += size) {
      newArr.push(arr.slice(i, i + size));
    }
    return newArr;
  }
}

C'est une solution géniale pour créer dynamiquement de nouvelles colonnes / lignes en fonction de la quantité d'éléments que vous itérez à partir de la base de données. Merci!

Gel
la source
-1

cela répond à la question originale qui est de savoir comment obtenir 1,2,3 dans une colonne. - demandé par kuppu le 8 février 14 à 13:47

code angularjs:

function GetStaffForFloor(floor) {
    var promiseGet = Directory_Service.getAllStaff(floor);
    promiseGet.then(function (pl) {
        $scope.staffList = chunk(pl.data, 3); //pl.data; //
    },
    function (errorOD) {
        $log.error('Errored while getting staff list.', errorOD);
    });
}
function chunk(array, columns) {
    var numberOfRows = Math.ceil(array.length / columns);

    //puts 1, 2, 3 into column
    var newRow = []; //array is row-based.
    for (var i = 0; i < array.length; i++) {
        var columnData = new Array(columns);
        if (i == numberOfRows) break;
        for (j = 0; j < columns; j++)
        {
            columnData[j] = array[i + numberOfRows * j];
        }
        newRow.push(columnData); 
    }
    return newRow;

    ////this works but 1, 2, 3 is in row
    //var newRow = [];
    //for (var i = 0; i < array.length; i += columns) {
    //    newRow.push(array.slice(i, i + columns)); //push effectively does the pivot. array is row-based.
    //}
    //return newRow;
};

Afficher le code (note: en utilisant bootstrap 3):

<div class="staffContainer">
    <div class="row" ng-repeat="staff in staffList">
        <div class="col-md-4" ng-repeat="item in staff">{{item.FullName.length > 0 ? item.FullName + ": Rm " + item.RoomNumber : ""}}</div>
    </div>
</div>
utilisateur2378769
la source
-1

Ce code aidera à aligner les éléments avec trois colonnes en mode lg et md, deux colonnes en mode sm et une colonne en mode xs

<div class="row">
<div ng-repeat="oneExt in configAddr.ext">
    <div class="col-xs-12 col-sm-6 col-md-4 col-lg-4">
        {$index+1}}. 
        <input type="text" name="macAdr{{$index+1}}" 
       id="macAddress" ng-model="oneExt.newValue" value=""/>
    </div>
</div>

Hari
la source