วิธีแยกข้อมูล ng-repeat ด้วยสามคอลัมน์โดยใช้ bootstrap


122

ฉันใช้ ng-repeat กับรหัสของฉันฉันมีกล่องข้อความจำนวน 'n' ตาม ng-repeat ฉันต้องการจัดแนวกล่องข้อความด้วยสามคอลัมน์

นี่คือรหัสของฉัน

<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
สมมติว่าคุณมีเก้า (9) คุณต้องการ 1,2,3 ในแถวหรือในคอลัมน์?
Gabriele Petrioli

คำตอบ:


255

แนวทางที่น่าเชื่อถือที่สุดและถูกต้องทางเทคนิคคือการแปลงข้อมูลในคอนโทรลเลอร์ นี่คือฟังก์ชั่นและการใช้งานที่เรียบง่าย

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

จากนั้นมุมมองของคุณจะมีลักษณะดังนี้:

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

หากคุณมีอินพุตใด ๆ ภายในng-repeatคุณอาจต้องการยกเลิกการเชื่อมต่อ / เข้าร่วมอาร์เรย์อีกครั้งเมื่อมีการแก้ไขข้อมูลหรือเมื่อส่ง นี่คือลักษณะที่จะปรากฏใน a $watchเพื่อให้ข้อมูลพร้อมใช้งานในรูปแบบดั้งเดิมที่ผสานอยู่เสมอ:

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

หลายคนชอบที่จะทำสิ่งนี้ให้สำเร็จในมุมมองด้วยตัวกรอง เป็นไปได้ แต่ควรใช้เพื่อการแสดงผลเท่านั้น! ถ้าคุณเพิ่มปัจจัยการผลิตที่อยู่ในมุมมองที่กรองนี้ก็จะทำให้เกิดปัญหาที่สามารถแก้ไขได้ แต่ไม่สวยหรือน่าเชื่อถือ

ปัญหาของตัวกรองนี้คือการส่งคืนอาร์เรย์ที่ซ้อนกันใหม่ทุกครั้ง Angular กำลังดูค่าส่งคืนจากตัวกรอง ครั้งแรกที่ตัวกรองทำงาน Angular จะรู้ค่าจากนั้นเรียกใช้อีกครั้งเพื่อให้แน่ใจว่าได้ทำการเปลี่ยนแปลงแล้ว ถ้าทั้งสองค่าเหมือนกันวงจรจะสิ้นสุดลง ถ้าไม่เช่นนั้นตัวกรองจะเริ่มทำงานซ้ำแล้วซ้ำเล่าจนกว่าจะเหมือนเดิมหรือ Angular ตระหนักว่ามีการวนรอบการย่อยที่ไม่สิ้นสุดเกิดขึ้นและปิดตัวลง เนื่องจากอาร์เรย์ / อ็อบเจ็กต์ที่ซ้อนกันใหม่ไม่ได้ถูกติดตามโดย Angular ก่อนหน้านี้จึงเห็นค่าที่ส่งคืนแตกต่างจากก่อนหน้านี้เสมอ ในการแก้ไขตัวกรอง "ไม่เสถียร" เหล่านี้คุณต้องรวมตัวกรองไว้ในmemoizeฟังก์ชัน lodashมีmemoizeฟังก์ชันและเวอร์ชันล่าสุดของ lodash ยังมีchunkฟังก์ชันดังนั้นเราจึงสามารถสร้างตัวกรองนี้ได้อย่างง่ายดายโดยใช้npmโมดูลและการคอมไพล์สคริปต์ด้วยbrowserifyor webpack.

ข้อควรจำ: แสดงเท่านั้น! กรองในคอนโทรลเลอร์หากคุณกำลังใช้อินพุต!

ติดตั้ง lodash:

npm install lodash-node

สร้างตัวกรอง:

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

และนี่คือตัวอย่างของตัวกรองนี้:

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

สั่งซื้อสินค้าในแนวตั้ง

1  4
2  5
3  6

เกี่ยวกับคอลัมน์แนวตั้ง (รายการจากบนลงล่าง) แทนที่จะเป็นแนวนอน (จากซ้ายไปขวา) การใช้งานที่แน่นอนขึ้นอยู่กับความหมายที่ต้องการ รายการที่แบ่งไม่เท่ากันสามารถกระจายได้หลายวิธี วิธีหนึ่งมีดังนี้

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

อย่างไรก็ตามวิธีที่ง่ายที่สุดและง่ายที่สุดในการรับคอลัมน์คือการใช้คอลัมน์ CSS :

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

ขอบคุณสำหรับความช่วยเหลือของคุณ. แต่การใช้ carousel กับ ui-chart ในเชิงมุมไม่สามารถวาดแผนภูมิ bt carousel ได้ดี รหัสของฉันคือ <carousel interval = "myInterval"> <slide ng-repeat = "milestone in mileStone | split: 4" active = "slide.active"> <div class = "col-md-3" ng-repeat = " Milestone1 ในไมล์สโตน "> <div style =" text-align: center; "> <div ui-chart =" data "chart-options =" ​​chartOptions "> </div> </div> </div> </ slide > </carousel> และฉันเริ่มต้นตัวแปรขอบเขตของฉันเป็นข้อมูล JSON ที่สำคัญ
kuppu

1
@ M59 ตอนนี้ฟังก์ชั่นนี้การแสดงข้อมูลในแถวแรกแถวที่สองa b c d e fฉันสามารถแสดงa b ในคอลัมน์แรกc dในคอลัมน์ที่สองและe fในคอลัมน์ที่สามได้หรือไม่? ขอบคุณ

1
@ ifch0o1 คุณจะถูกต้องถ้าเป็น[].concat.call([], val)เช่นนั้น คุณต้องพิจารณาสิ่งที่applyทำ เป็นอาร์เรย์ของอาร์เรย์และเราต้องการที่จะผ่านหนึ่งของอาร์เรย์แต่ละเหล่านั้นภายในของมันเป็นข้อโต้แย้งที่จะval concatฉันคิดว่าคุณกำลังมุ่งเน้นไปที่บริบท[]ซึ่งไม่ใช่ประเด็นที่นี่ เราต้องการอะไรเรา[].concat(val[1], val[2], val[3], etc)จึงต้องการapply([], val)
m59

1
@bahadir ฉันปรับปรุงคำตอบให้ชัดเจนยิ่งขึ้น ตรวจสอบสิ่งที่เกิดขึ้นถ้าคุณทำให้ตัวกรองที่ให้ผลตอบแทนเพียง[]VS และ[[]] [{}]อาร์เรย์ / ออบเจ็กต์ที่ซ้อนกันทำให้ Angular เห็นผลลัพธ์ที่แตกต่างกันในทุกๆครั้งfilterและยังคงทำซ้ำเพื่อค้นหาผลลัพธ์ที่จะยังคงเหมือนเดิม (คงที่)
m59

1
คุณกำลังสแปมความคิดเห็นจริงๆ :) ลองด้วยตัวคุณเอง var x = [1,2,3]; var y = [1,2,3]; console.log(x === y);การตรวจสอบอย่างละเอียดหมายถึงการกำหนดสตริงและการเปรียบเทียบสตริงซึ่งมีความเสี่ยงเนื่องจากอ็อบเจ็กต์อาจไม่รัดกุมหรือตรวจสอบคุณสมบัติแต่ละรายการซ้ำทีละรายการ ฉันคิดว่า Angular สามารถใช้สิ่งนั้นกับตัวกรองได้ แต่ฉันแน่ใจว่ามีเหตุผลที่ดีที่พวกเขาไม่ทำ อาจเป็นเพราะตัวกรองส่วนใหญ่มีไว้สำหรับการปรับเปลี่ยนชุดข้อมูลอย่างง่าย ๆ ไม่ใช่การยกเครื่องใหม่ทั้งหมดพร้อมกับการเปลี่ยนแปลงโครงสร้าง
m59

64

วิธีนี้ง่ายมาก:

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>

สาธิตใน FIDDLE

ใส่คำอธิบายภาพที่นี่


3
ตอบดีที่สุด! และทำในสิ่งที่ต้องการด้วยคำสั่งดั้งเดิม! Congratz!
Renan Franca

1
วิธีนี้ใช้งานได้ แต่สำหรับแนวทางปฏิบัติที่ดีที่สุดคุณอาจไม่ควรใช้ตารางเพื่อกำหนดเค้าโครงในมาร์กอัปของคุณ :)
Dave Cooper

2
ในฐานะที่เป็น @DaveCooper กล่าวถึงที่นี่เป็นรูปแบบทางเลือกโดยไม่ต้องตาราง: plnkr.co/edit/81oj8mHaNyfQpCmRBWO4?p=preview พิจารณาตารางสำหรับข้อมูลแบบตาราง แต่อย่างอื่นนี่เป็นเค้าโครงที่ดีกว่าสำหรับอุปกรณ์เคลื่อนที่และขนาดหน้าจอที่เปลี่ยนแปลงได้
Zymotik

1
นี่เป็นทางออกที่ดีที่สุด ต้องใช้เวลาในการค้นหาสิ่งที่ไม่ชอบมาพากลทั้งหมดเมื่อใช้เฟรมเวิร์กใหม่ แต่ ng-switch นั้นเป็นสิ่งที่มาจากสวรรค์
Zoran

หากคุณใช้ div แทนตารางคุณสามารถวางng-switch-when="0"บน div ด้านนอกได้ 1 ครั้งแทนที่จะเป็นทั้ง 3 รายการ
Hans Wouters

19

โซลูชันที่สะอาดและปรับเปลี่ยนได้โดยไม่ต้องมีการจัดการข้อมูล :

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

นี่เป็นวิธีง่ายๆสำหรับการแสดงผลข้อมูลเป็นแถวและคอลัมน์แบบไดนามิกโดยไม่จำเป็นต้องจัดการอาร์เรย์ของข้อมูลที่คุณต้องการแสดง นอกจากนี้หากคุณลองปรับขนาดหน้าต่างเบราว์เซอร์คุณจะเห็นว่าเส้นตารางปรับตามขนาดของหน้าจอ / div แบบไดนามิก

(ฉันยังเพิ่มคำต่อท้าย {{$ index}} ให้กับ id ของคุณเนื่องจาก ng-repeat จะพยายามสร้างหลายองค์ประกอบด้วย id เดียวกันหากคุณไม่ทำเช่นนั้น)

ตัวอย่างการทำงานที่คล้ายกัน


1
ฉันเชื่อว่า OP ต้องการมาร์กอัปสำหรับแถว / คอลัมน์ Bootstrap ของ Twitter แต่สิ่งนี้อาจเป็นประโยชน์กับใครบางคน อย่างไรก็ตามคุณต้องใส่รหัสและคำอธิบายในคำตอบของคุณ คำตอบเฉพาะลิงก์จะถูกลบออก
m59

@ m59 คำตอบที่อัปเดต. ขอบคุณสำหรับคำแนะนำ
Cumulo Nimbus

1
บิ๊ก +1 ไม่จำเป็นต้องมีการจัดการข้อมูล สิ่งนี้ทำงานได้สมบูรณ์แบบสำหรับความต้องการของฉันที่ต้องการแยกข้อมูลในช่วงโดยใช้ ng-repeat เป็น 2 คอลัมน์เพื่อให้ Bootstrap modal ของฉันไม่นาน! ฉันแปลกใจว่ามันง่ายแค่ไหนในการนำไปใช้! <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>ที่อยู่ใน `` กิริยา - ร่างกาย ''
Christine268

15

คำตอบของ m59 ค่อนข้างดี สิ่งหนึ่งที่ฉันไม่ชอบคือมันใช้divs สำหรับสิ่งที่อาจเป็นข้อมูลสำหรับตาราง

ดังนั้นเมื่อใช้ร่วมกับฟิลเตอร์ของ m59 (คำตอบด้านบน) นี่คือวิธีแสดงในตาราง

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

7

ต่อไปนี้เป็นวิธีที่ง่ายกว่า:

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

คำตอบของ Cumulo Nimbus มีประโยชน์สำหรับฉัน แต่ฉันต้องการให้ตารางนี้พันด้วย div ซึ่งสามารถแสดงแถบเลื่อนเมื่อรายการยาวเกินไป

เพื่อให้บรรลุสิ่งนี้ฉันได้เพิ่มstyle="height:200px; overflow:auto"div ลงในตารางซึ่งทำให้แสดงเป็นคอลัมน์เดียว

ตอนนี้ใช้ได้กับความยาวอาร์เรย์หนึ่ง


เมื่อมีเพียง 1 รายการในอาร์เรย์จะไม่แสดงแถวแรก เพื่อแก้ไขการเปลี่ยนแปลงนี้ ng-hide="$index%2!==0"
Anuj Pandey

4

ฉันมีฟังก์ชั่นและเก็บไว้ในบริการเพื่อให้ฉันสามารถใช้งานได้ทั่วแอพของฉัน:

บริการ:

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

});

ควบคุม:

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

มาร์กอัป:

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

แม้ว่าสิ่งนี้จะยอดเยี่ยม แต่ก็ไม่ได้ช่วยอะไรเมื่อใช้ตัวกรองอื่น ๆ เช่น orderBy หรือตัวกรอง
Robbie Smith

2

แนวทางของฉันคือส่วนผสมของสิ่งต่างๆ

วัตถุประสงค์ของฉันคือการมีเส้นตารางที่ปรับให้เข้ากับขนาดหน้าจอ ฉันต้องการ 3 คอลัมน์สำหรับlg2 คอลัมน์สำหรับsmและmdและ 1 คอลัมน์สำหรับxs.

ก่อนอื่นฉันสร้างฟังก์ชันขอบเขตต่อไปนี้โดยใช้$windowบริการเชิงมุม:

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

จากนั้นฉันใช้คลาสที่เสนอโดย @Cumulo Nimbus:

.new-row {
    clear: left;
}

ใน div ที่มีng-repeatฉันได้เพิ่มresizableคำสั่งตามที่อธิบายไว้ในหน้านี้เพื่อให้ทุกครั้งที่มีการปรับขนาดหน้าต่าง$windowบริการเชิงมุมจะได้รับการอัปเดตด้วยค่าใหม่

ท้ายที่สุดแล้วใน div ซ้ำฉันมี:

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

โปรดแจ้งให้เราทราบข้อบกพร่องใด ๆ ในแนวทางนี้

หวังว่าจะเป็นประโยชน์


2

เคล็ดลับง่ายๆด้วย CSS "clearfix" ที่แนะนำโดย 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>

ข้อดีหลายประการ: มีประสิทธิภาพรวดเร็วโดยใช้คำแนะนำของ Boostrap หลีกเลี่ยงปัญหาการแยกส่วนของ $ ที่เป็นไปได้และไม่เปลี่ยนแปลงโมเดลเชิงมุม


1

ตัวอย่างนี้สร้างตัวทำซ้ำที่ซ้อนกันซึ่งข้อมูลภายนอกรวมถึงอาร์เรย์ภายในที่ฉันต้องการแสดงรายการในสองคอลัมน์ แนวคิดนี้จะเป็นจริงสำหรับสามคอลัมน์ขึ้นไป

ในคอลัมน์ด้านในฉันทำซ้ำ "แถว" จนกว่าจะถึงขีด จำกัด ขีด จำกัด ถูกกำหนดโดยการหารความยาวของอาร์เรย์ของรายการด้วยจำนวนคอลัมน์ที่ต้องการในกรณีนี้ด้วยสองคอลัมน์ วิธีการหารอยู่บนคอนโทรลเลอร์และส่งผ่านความยาวอาร์เรย์ปัจจุบันเป็นพารามิเตอร์ จากนั้นฟังก์ชัน JavaScript slice (0, array.length / columnCount) จะใช้ขีด จำกัด กับตัวทำซ้ำ

จากนั้นตัวทำซ้ำคอลัมน์ที่สองจะถูกเรียกใช้และทำซ้ำ slice (array.length / columnCount, array.length) ซึ่งสร้างครึ่งหลังของอาร์เรย์ในคอลัมน์ที่สอง

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

หวังว่านี่จะช่วยในการมองหาวิธีแก้ปัญหาในอีกทางหนึ่ง (ปล. นี่เป็นกระทู้แรกของฉันที่นี่! :-))



1

นี่เป็นวิธีที่แฮ็กง่าย เป็นคู่มือมากขึ้นและจบลงด้วยมาร์กอัปที่ยุ่งเหยิง ฉันไม่แนะนำสิ่งนี้ แต่มีบางสถานการณ์ที่อาจเป็นประโยชน์

นี่คือลิงค์ซอ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"},
        ...
    ];
});

การตั้งค่านี้ต้องการให้เราใช้ Math บางอย่างในมาร์กอัป: / ดังนั้นคุณจะต้องฉีด Math โดยเพิ่มบรรทัดนี้: $scope.Math = Math;


1

คำตอบทั้งหมดนี้ดูเหมือนจะถูกออกแบบมาอย่างมาก

วิธีที่ง่ายที่สุดคือการตั้งค่า div อินพุตใน bootstrap คอลัมน์ col-md-4 จากนั้น bootstrap จะจัดรูปแบบเป็น 3 คอลัมน์โดยอัตโนมัติเนื่องจากลักษณะ 12 คอลัมน์ของ 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>

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

จากคำตอบที่ดีมากของ m59 ฉันพบว่าอินพุตของโมเดลจะเบลอหากมีการเปลี่ยนแปลงดังนั้นคุณสามารถเปลี่ยนได้ครั้งละหนึ่งอักขระเท่านั้น นี่เป็นรายการใหม่สำหรับรายการวัตถุสำหรับทุกคนที่ต้องการ:

แก้ไขอัปเดตเพื่อจัดการตัวกรองหลายตัวในหน้าเดียว

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

และนี่จะเป็นการใช้งาน:

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

เท่าที่ฉันสามารถบอกได้สิ่งนี้ควรใช้งานได้เกือบตลอดเวลา แต่ตรรกะการแคชนั้นดูไม่น่าเชื่อถืออย่างสิ้นเชิงและการส่งผ่านในขอบเขตนั้นไม่สะดวก ฉันขอแนะนำให้กรองภายในคอนโทรลเลอร์เมื่อจำเป็นต้องใช้อินพุต เป็นแนวทางที่ถูกต้องทางเทคนิคอยู่ดี
m59

0

ฉันใหม่ใน bootstrap และ angularjs แต่สิ่งนี้สามารถทำให้ Array ต่อ 4 รายการเป็นกลุ่มเดียวผลลัพธ์จะเหมือนกับ 3 คอลัมน์ เคล็ดลับนี้ใช้หลักการแบ่ง 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 มีวิธีการแบบก้อนในตัวซึ่งตอนนี้ฉันใช้เป็นการส่วนตัว: https://lodash.com/docs#chunk

จากสิ่งนี้รหัสคอนโทรลเลอร์อาจมีลักษณะดังต่อไปนี้:

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

ดูรหัส:

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

0

อีกวิธีหนึ่งคือตั้งค่าwidth:33.33%; float:leftเป็น wrapper div ดังนี้:

<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

ฉันพบว่าตัวเองอยู่ในกรณีที่คล้ายกันต้องการสร้างกลุ่มการแสดงผล 3 คอลัมน์ อย่างไรก็ตามแม้ว่าฉันจะใช้ bootstrap แต่ฉันก็พยายามแยกกลุ่มเหล่านี้ออกเป็น div หลักที่แตกต่างกัน ฉันยังต้องการทำสิ่งที่เป็นประโยชน์โดยทั่วไป

ฉันเข้าหามันด้วย 2 ng-repeatดังต่อไปนี้:

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

สิ่งนี้ทำให้ง่ายมากในการเปลี่ยนคอลัมน์จำนวนอื่นและแยกออกเป็น div พาเรนต์หลาย ๆ คอลัมน์


0

ในกรณีที่มีคนต้องการ Angular 7 (และรุ่นที่สูงกว่า) นี่คือตัวอย่างที่ฉันใช้ในแอปพลิเคชันของฉัน:

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>

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

นี่เป็นโซลูชันที่ยอดเยี่ยมสำหรับการสร้างคอลัมน์ / แถวใหม่แบบไดนามิกขึ้นอยู่กับจำนวนรายการที่คุณทำซ้ำจากฐานข้อมูล ขอบคุณ!


-1

สิ่งนี้ตอบคำถามเดิมซึ่งเป็นวิธีรับ 1,2,3 ในคอลัมน์ - ถามโดย kuppu 8 ก.พ. 57 เวลา 13:47 น

รหัส 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;
};

ดูรหัส (หมายเหตุ: การใช้ 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

รหัสนี้จะช่วยจัดเรียงองค์ประกอบด้วยสามคอลัมน์ใน lg และโหมด md สองคอลัมน์ในโหมด sm และคอลัมน์เดียวคือโหมด 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>

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.