jak podzielić dane ng-repeat z trzema kolumnami za pomocą bootstrap


122

Używam ng-repeat z moim kodem Mam 'n' liczbę pól tekstowych na podstawie ng-repeat. Chcę wyrównać pole tekstowe z trzema kolumnami.

to jest mój kod

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

1
więc zakładając, że masz dziewięć (9), chcesz 1,2,3 w rzędzie czy w kolumnie?
Gabriele Petrioli,

Odpowiedzi:


255

Najbardziej niezawodnym i technicznie poprawnym podejściem jest transformacja danych w kontrolerze. Oto prosta funkcja i użycie fragmentu.

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

Wtedy Twój widok wyglądałby tak:

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

Jeśli masz jakiekolwiek dane wejściowe w ramach ng-repeat, prawdopodobnie będziesz chciał odblokować / ponownie dołączyć tablice, gdy dane są modyfikowane lub przesyłane. Oto jak wyglądałoby to w formacie a $watch, aby dane były zawsze dostępne w oryginalnym, scalonym formacie:

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

Wiele osób woli to osiągnąć w widoku z filtrem. Jest to możliwe, ale powinno być używane tylko do celów wyświetlania! Jeśli dodasz dane wejściowe w tym przefiltrowanym widoku, spowoduje to problemy, które można rozwiązać, ale nieładne ani niezawodne .

Problem z tym filtrem polega na tym, że za każdym razem zwraca nowe zagnieżdżone tablice. Angular obserwuje wartość zwracaną przez filtr. Przy pierwszym uruchomieniu filtru Angular zna wartość, a następnie uruchamia go ponownie, aby upewnić się, że została zmieniona. Jeśli obie wartości są takie same, cykl jest zakończony. Jeśli nie, filtr będzie uruchamiał się raz po raz, aż będą takie same, lub Angular zorientuje się, że występuje nieskończona pętla trawienia i wyłączy się. Ponieważ nowe zagnieżdżone tablice / obiekty nie były wcześniej śledzone przez Angular, zawsze widzi wartość zwracaną jako inną niż poprzednia. Aby naprawić te „niestabilne” filtry, musisz umieścić filtr w memoizefunkcji. lodashma memoizefunkcję, a najnowsza wersja lodash zawiera również chunkfunkcję, więc możemy utworzyć ten filtr w bardzo prosty sposób za pomocąnpmmodułów i kompilowanie skryptu za pomocą browserifylub webpack.

Pamiętaj: tylko wyświetlaj! Filtruj w kontrolerze, jeśli używasz wejść!

Zainstaluj lodash:

npm install lodash-node

Utwórz filtr:

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

A oto próbka z tym filtrem:

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

Zamawiaj pozycje pionowo

1  4
2  5
3  6

Jeśli chodzi o kolumny pionowe (lista od góry do dołu), a nie poziome (od lewej do prawej), dokładna implementacja zależy od pożądanej semantyki. Listy, które dzielą się nierównomiernie, można podzielić na różne sposoby. Oto jeden sposób:

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

Jednak najbardziej bezpośrednim i po prostu prostym sposobem uzyskania kolumn jest użycie kolumn CSS :

.columns {
  columns: 3;
}
<div class="columns">
  <div ng-repeat="item in ['a','b','c','d','e','f','g']">
    {{item}}
  </div>
</div>

Dzięki za pomoc. Ale używanie karuzeli z wykresem ui w trybie kątowym nie może narysować karuzeli wykresu bt działa dobrze. mój kod to <carousel interval = "myInterval"> <slide ng-repeat = "kamień milowy w mileStone | split: 4" active = "slide.active"> <div class = "col-md-3" ng-repeat = " kamień milowy1 w kamieniu milowym "> <div style =" text-align: center; "> <div ui-chart =" data "chart-options =" ​​chartOptions "> </div> </div> </div> </ slide > </carousel> I zainicjowałem moją zmienną zasięgu jako kluczowe dane JSON.
kuppu

1
@ m59 W tej chwili ta funkcja wyświetla dane w pierwszym wierszu w a b cdrugim wierszu d e f. Czy mogę wyświetlać a b w pierwszej kolumnie c dw drugiej kolumnie i e fw trzeciej kolumnie? Dzięki

1
@ Ifch0o1 Byłbyś poprawny, gdyby tak było [].concat.call([], val). Musisz się zastanowić, co się applydzieje. valjest tablicą tablic i chcemy przekazać każdą z tych tablic wewnątrz niej jako argumenty concat. Myślę, że skupiasz się na kontekście [], o co tutaj nie chodzi. Chcemy [].concat(val[1], val[2], val[3], etc), więc potrzebujemyapply([], val)
m59

1
@bahadir Zaktualizowałem odpowiedź, aby była bardziej przejrzysta. Sprawdź, co się stanie, jeśli utworzysz filtr, który po prostu zwraca []vs [[]]i [{}]. Zagnieżdżona tablica / obiekt sprawia, że ​​Angular widzi inny wynik na każdym filteri powtarza się, aby wynik pozostał taki sam (stabilizacja).
m59

1
Naprawdę spamujesz komentarze :) Spróbuj sam. var x = [1,2,3]; var y = [1,2,3]; console.log(x === y);Dogłębne sprawdzanie oznacza określanie i porównywanie ciągów, co jest ryzykowne, ponieważ obiekt może nie być poddawany stringifikacji, lub rekursywne sprawdzanie każdej właściwości indywidualnie. Myślę, że Angular mógłby to zaimplementować w przypadku filtrów, ale jestem pewien, że jest dobry powód, dla którego tego nie zrobili. Prawdopodobnie dlatego, że chodziło im głównie o filtry do prostej modyfikacji zbioru danych, a nie do całkowitego remontu ze zmianami w strukturze.
m59

64

To rozwiązanie jest bardzo proste:

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

wprowadź opis obrazu tutaj


3
Najlepsza odpowiedź! I rób to, co trzeba, z natywnymi dyrektywami! Congratz!
Renan Franca

1
To rozwiązanie działa, ale jeśli chodzi o najlepsze praktyki, prawdopodobnie nie powinieneś używać tabel do definiowania układu w swoim znaczniku :)
Dave Cooper

2
Jak wspomina @DaveCooper, oto alternatywny układ bez tabel: plnkr.co/edit/81oj8mHaNyfQpCmRBWO4?p=preview . Rozważ tabele dla danych tabelarycznych, ale poza tym jest to lepszy układ dla urządzeń mobilnych i różnych rozmiarów ekranu.
Zymotik

1
To zdecydowanie najlepsze rozwiązanie. Potrzeba czasu, aby znaleźć wszystkie dziwactwa podczas korzystania z nowego frameworka, ale ng-switch to dar niebios
Zoran

Jeśli zamiast tabeli wybierasz elementy div, możesz umieścić ng-switch-when="0"jeden element na zewnętrznym div zamiast wszystkich trzech elementów.
Hans Wouters

19

Czyste, elastyczne rozwiązanie, które nie wymaga manipulacji danymi :

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>

CSS:

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

JavaScript:

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

Jest to proste rozwiązanie do dynamicznego renderowania danych w wierszach i kolumnach bez konieczności manipulowania tablicą danych, którą próbujesz wyświetlić. Dodatkowo, jeśli spróbujesz zmienić rozmiar okna przeglądarki, zobaczysz, że siatka dynamicznie dostosowuje się do rozmiaru ekranu / div.

(Dodałem również sufiks {{$ index}} do twojego identyfikatora, ponieważ ng-repeat spróbuje utworzyć wiele elementów z tym samym identyfikatorem, jeśli tego nie zrobisz.)

Podobny przykład roboczy


1
Wydaje mi się, że OP chciał mieć znaczniki dla wierszy / kolumn Twittera Bootstrap, ale może to być pomocne dla kogoś. Musisz jednak umieścić kod i wyjaśnienie w swojej odpowiedzi. Odpowiedzi zawierające tylko linki zostaną usunięte.
m59

@ m59 Zaktualizowana odpowiedź. Dzięki za sugestię
Cumulo Nimbus

1
Duże +1 za nie wymaga manipulacji danymi . To zadziałało idealnie dla moich potrzeb, aby rozdzielić dane w zakresie za pomocą ng-powtarzania na 2 kolumny, aby mój modał Bootstrap nie był tak długi! Byłem zaskoczony, jak proste było to do wykonania! <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>To jest wewnątrz „ciała modalnego”.
Christine268

15

odpowiedź m59 jest całkiem dobra. Jedną rzeczą, która mi się nie podoba, jest to, że używa divs do tego, co może być danymi dla tabeli.

Więc w połączeniu z filtrem m59 (odpowiedź gdzieś powyżej), oto jak wyświetlić go w tabeli.

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

7

Oto prostszy sposób:

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

Odpowiedź Cumulo Nimbus jest dla mnie przydatna, ale chcę, aby ta siatka była zawinięta w element div, który może wyświetlać pasek przewijania, gdy lista jest zbyt długa.

Aby to osiągnąć, dodałem style="height:200px; overflow:auto"element div dookoła tabeli, co powoduje, że jest on wyświetlany jako pojedyncza kolumna.

Teraz działa dla tablicy o długości jeden.


gdy w tablicy jest tylko 1 element, nie wyświetlałby samego pierwszego wiersza. naprawić tę zmianę ng-hide="$index%2!==0"
Anuj Pandey

4

Mam funkcję i zapisałem ją w usłudze, dzięki czemu mogę jej używać w całej mojej aplikacji:

Usługa:

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

});

Kontroler:

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

Narzut:

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

Chociaż jest to fajne, nie pomaga w przypadku korzystania z innych filtrów, takich jak orderBy lub filter.
Robbie Smith

2

Moje podejście było mieszanką rzeczy.

Moim celem było dostosowanie siatki do rozmiaru ekranu. Chciałem 3 kolumny dla lg, 2 kolumny dla smi mdi 1 kolumnę dla xs.

Najpierw utworzyłem następującą funkcję zakresu, używając $windowusługi kątowej :

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

Następnie skorzystałem z klasy zaproponowanej przez @Cumulo Nimbus:

.new-row {
    clear: left;
}

W elemencie div zawierającym element ng-repeatdodałem resizabledyrektywę, jak wyjaśniono na tej stronie , dzięki czemu za każdym razem, gdy rozmiar okna jest zmieniany, $windowusługa kątowa jest aktualizowana o nowe wartości.

Ostatecznie w powtarzanym div mam:

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

Proszę, daj mi znać o wszelkich wadach tego podejścia.

Mam nadzieję, że to może być pomocne.


2

Prosta sztuczka z "clearfix" CSS polecana przez 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>

Wiele zalet: wydajnie, szybko, korzystając z zaleceń Boostrap, unikając możliwych problemów z trawieniem i nie zmieniając modelu Angular.


1

Ten przykład tworzy zagnieżdżony repeater, w którym dane zewnętrzne zawierają wewnętrzną tablicę, którą chciałem wyświetlić w dwóch kolumnach. Koncepcja byłaby prawdziwa dla trzech lub więcej kolumn.

W wewnętrznej kolumnie powtarzam „wiersz” aż do osiągnięcia limitu. Limit jest określany przez podzielenie długości tablicy elementów przez liczbę żądanych kolumn, w tym przypadku przez dwa. Metoda dzielenia znajduje się na kontrolerze i jako parametr jest przekazywana bieżąca długość tablicy. Następnie funkcja wycinka JavaScript (0, array.length / columnCount) zastosowała ograniczenie do repeatera.

Następnie wywoływany jest wtórnik drugiej kolumny i powtarza wycinek (array.length / columnCount, array.length), który tworzy drugą połowę tablicy w drugiej kolumnie.

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

Mam nadzieję, że pomoże to spojrzeć na rozwiązanie w jeszcze inny sposób. (PS to mój pierwszy post tutaj! :-))


1

Naprawiam bez .row

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

i css

.left {
  float: left;
}

1

Oto łatwy sposób na zrobienie tego. Jest bardziej ręczny i kończy się niechlujnymi znacznikami. Nie polecam tego, ale są sytuacje, w których może to być przydatne.

Oto link do skrzypiec 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"},
        ...
    ];
});

Ta konfiguracja wymaga od nas użycia matematyki w znaczniku: /, więc musisz wstrzyknąć Math, dodając tę ​​linię: $scope.Math = Math;


1

Wszystkie te odpowiedzi wydają się przesadnie skomplikowane.

Zdecydowanie najprostszą metodą byłoby skonfigurowanie wejściowych elementów div w układzie ładowania początkowego col-md-4, a następnie bootstrap automatycznie sformatuje go w 3 kolumnach ze względu na 12-kolumnowy charakter programu ładującego:

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

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>

0

Opierając się na bardzo dobrej odpowiedzi m59. Odkryłem, że dane wejściowe modelu byłyby rozmyte, gdyby się zmieniły, więc można zmieniać tylko jeden znak na raz. To jest nowa lista obiektów dla każdego, kto tego potrzebuje:

EDYCJA Zaktualizowano w celu obsługi wielu filtrów na jednej stronie

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

A to byłoby użycie:

<div ng-repeat="row in items | partition:3:this">
  <span class="span4">
    {{ $index }}
  </span>
</div>

O ile wiem, powinno to działać przez większość czasu, ale ta logika buforowania nie wygląda na całkowicie niezawodną, ​​a przekazywanie w zakresie jest niezręczne. Naprawdę zalecam filtrowanie w kontrolerze, gdy potrzebne są wejścia. I tak jest to technicznie poprawne podejście.
m59

0

Jestem nowy w bootstrap i angularjs, ale może to również sprawić, że Array per 4 items jako jedna grupa, a wynik będzie prawie jak 3 kolumny. Ta sztuczka wykorzystuje zasadę linii przerwania 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>

0

Lodash ma teraz wbudowaną metodę chunk, której osobiście używam: https://lodash.com/docs#chunk

Na tej podstawie kod kontrolera może wyglądać następująco:

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

Wyświetl kod:

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

0

Innym sposobem jest ustawienie width:33.33%; float:leftopakowującego elementu div w następujący sposób:

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

0

Znalazłem się w podobnym przypadku, chcąc wygenerować grupy wyświetlania po 3 kolumny każda. Jednak, mimo że używałem bootstrapu, próbowałem podzielić te grupy na różne nadrzędne elementy DIV. Chciałem też zrobić coś ogólnie użytecznego.

Podszedłem do tego z 2 ng-repeatjak poniżej:

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

Dzięki temu bardzo łatwo jest zmienić liczbę kolumn i podzielić je na kilka nadrzędnych elementów div.


0

Na wszelki wypadek, gdyby ktoś chciał mieć Angular 7 (i wyższą wersję), oto przykład, którego użyłem w jednej z moich aplikacji:

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>

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

Jest to świetne rozwiązanie do dynamicznego tworzenia nowych kolumn / wierszy w zależności od tego, ile elementów iterujesz z bazy danych. Dzięki!


-1

To odpowiada na pierwotne pytanie, jak uzyskać 1,2,3 w kolumnie. - zapytał kuppu 8 lutego 2014 o 13:47

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

Wyświetl kod (uwaga: używając 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>

-1

Ten kod pomoże wyrównać elementy z trzema kolumnami w trybie lg i md, dwiema kolumnami w trybie sm, a pojedyncza kolumna w trybie 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>

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.