เชิงมุม ng-repeat ในสิ่งที่ตรงกันข้าม


227

ฉันจะรับอาเรย์กลับด้านเป็นมุมได้อย่างไร? ฉันพยายามใช้ตัวกรอง orderBy แต่ต้องมีเพรดิเคต (เช่น 'ชื่อ') เพื่อจัดเรียง:

<tr ng-repeat="friend in friends | orderBy:'name':true">
      <td>{{friend.name}}</td>
      <td>{{friend.phone}}</td>
      <td>{{friend.age}}</td>
<tr>

มีวิธีการย้อนกลับอาร์เรย์เดิมโดยไม่ต้องเรียงลำดับ เช่นนั้น:

<tr ng-repeat="friend in friends | orderBy:'':true">
      <td>{{friend.name}}</td>
      <td>{{friend.phone}}</td>
      <td>{{friend.age}}</td>
<tr>


@QuiteNothing นั่นเป็นวิธีที่ถูกต้องหากคุณต้องการย้อนกลับอาร์เรย์ด้วยนิพจน์ ในกรณีนี้คำถามคือวิธีการกราบไหว้อาร์เรย์โดยไม่ต้องหนึ่ง
JayQuerie.com

<tr ng-repeat = "เพื่อนในเพื่อน | orderBy: '- ชื่อ'">
desmati

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

ใช้ตัวกรองเพื่อเปลี่ยนng-repeatพฤติกรรมเสมอ! @ เทรเวอร์อาวุโสทำงานได้ดี
Amir Savand

คำตอบ:


329

ฉันขอแนะนำให้ใช้ตัวกรองที่กำหนดเองเช่นนี้:

app.filter('reverse', function() {
  return function(items) {
    return items.slice().reverse();
  };
});

ซึ่งสามารถใช้เช่น:

<div ng-repeat="friend in friends | reverse">{{friend.name}}</div>

ดูการทำงานที่นี่: การสาธิตพลั่วเกอร์


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


21
ดี! เพิ่งทราบว่าitems.reverse()ปรับเปลี่ยนอาร์เรย์แทนเพียงสร้างใหม่และส่งคืน
Anders Ekdahl

12
ขอบคุณ! ฉันมองข้ามสิ่งนั้นไป ฉันโยนslice()เพื่อแก้ไขปัญหานั้น
JayQuerie.com

9
คุณควรเพิ่มif (!angular.isArray(items)) return false;เพื่อตรวจสอบว่าคุณมีอาร์เรย์ก่อนที่จะพยายามย้อนกลับ
respectTheCode

6
จำเป็นต้องมีการป้องกันมากกว่ากับโมฆะควรใช้สิ่งต่อไปนี้แทน: คืนไอเท็ม? items.slice (). reverse (): [];
Chris Yeung

5
@Chris Yeung: ไม่แนะนำให้คืนค่าว่าง "[]" เมื่อ null ดีกว่าที่จะคืนค่าเดิม
ศิวะ

202

นี่คือสิ่งที่ฉันใช้:

<alert ng-repeat="alert in alerts.slice().reverse()" type="alert.type" close="alerts.splice(index, 1)">{{$index + 1}}: {{alert.msg}}</alert>

ปรับปรุง:

คำตอบของฉันคือโอเคสำหรับ Angular รุ่นเก่า ตอนนี้คุณควรจะใช้

ng-repeat="friend in friends | orderBy:'-'"

หรือ

ng-repeat="friend in friends | orderBy:'+':true"

จากhttps://stackoverflow.com/a/26635708/1782470


Uing track byนี่เป็นวิธีเดียวที่ใช้ได้สำหรับฉัน

@delboud คุณควรใช้แทร็กโดยหลังจากng-repeat="friend in friends | orderBy:'+': true track by $index"
order

125

ขออภัยสำหรับนำขึ้นนี้หลังจากปี แต่มีใหม่แก้ปัญหาได้ง่ายขึ้นซึ่งทำงานให้กับเชิงมุม v1.3.0-rc.5 และต่อมา

มันถูกกล่าวถึงในเอกสาร : "หากไม่มีการจัดเตรียมคุณสมบัติ (เช่น '+') องค์ประกอบอาร์เรย์จะถูกใช้เพื่อเปรียบเทียบการเรียงลำดับ" ดังนั้นการแก้ปัญหาจะเป็น:

ng-repeat="friend in friends | orderBy:'-'" หรือ

ng-repeat="friend in friends | orderBy:'+':true"

วิธีนี้ดูเหมือนจะดีกว่าเพราะไม่ได้แก้ไขอาร์เรย์และไม่ต้องการทรัพยากรการคำนวณเพิ่มเติม (อย่างน้อยในรหัสของเรา) ฉันได้อ่านคำตอบที่มีอยู่ทั้งหมดแล้วและยังคงต้องการคำตอบนี้


1
ขอบคุณสำหรับทิป! ในฐานะที่เป็นหัวขึ้นสำหรับคนอื่นที่อ่านข้อความนี้ดูเหมือนว่ามันจะไม่ทำงานใน rc4 ( v1.3.0-rc.4) หากใครได้รับโอกาสลองในรีลีสใหม่แจ้งให้เราทราบ!
mikermcneil

1
@mikermcneil ขอบคุณสำหรับความคิดเห็น! ตามเอกสารชุดเดียวกันมันควรเริ่มทำงานจากv1.3.0-rc.5( rc.5 docs vs rc.4 docs ) ฉันได้อัปเดตคำตอบแล้ว
Dmitry Gonchar

1
ไม่ทำงานสำหรับฉัน (v1.3.5) พยายามorderBy:'+':true, orderBy:'-':true, orderBy:'-':false, orderBy:'+':false:(
โค

2
@Cody ขออภัยสำหรับคำตอบที่ล่าช้า ที่นี่คุณจะไป - ตัวอย่างการทำงานที่มีมุม v1.3.5 jsfiddle.net/dmitry_gonchar/L98foxhm/1 น่าจะเป็นปัญหาอยู่ในที่อื่น
Dmitry Gonchar

1
@alevkon True แต่จะใช้งานได้หากคุณระบุฟิลด์ ('+ id', '-id' fe) บางทีนี่อาจเป็นข้อผิดพลาดใน Angular ว่ามันไม่ทำงานกับคำสั่งปกติถ้าคุณไม่ระบุฟิลด์? ฉันใช้วิธีนี้จากเอกสาร (ลิงก์อยู่ในคำตอบ) ดังนั้นฉันจึงประหลาดใจเช่นเดียวกับคุณ อย่างไรก็ตามคำถามคือวิธีการย้อนกลับอาร์เรย์
Dmitry Gonchar

54

คุณสามารถย้อนกลับด้วยพารามิเตอร์ $ index

<tr ng-repeat="friend in friends | orderBy:'$index':true">

13
ควรใช้งานได้ แต่ไม่ (ลองด้วยและไม่มีเครื่องหมายอัญประกาศ$index) ฉันใช้แองกูลาร์ 1.1.5
วิศวกร

2
ใช้งานได้สำหรับฉัน (ใช้คุณสมบัติในการเรียงลำดับแทน $ index) stackoverflow.com/questions/16261348/…
Certs

4
ไม่ทำงานกับ AngularJS 1.2.13 ฉันแก้ไขอาร์เรย์ของวัตถุเพื่อเพิ่มรหัสให้กับแต่ละวัตถุ id เป็นดัชนีของวัตถุภายในอาร์เรย์ จากนั้นได้ng-repeat="friend in friends | orderBy:'id':true"ผล
tanguy_k


17

คุณสามารถเรียกวิธีการในขอบเขตของคุณเพื่อย้อนกลับให้คุณเช่นนี้

<!doctype html>
<html ng-app="myApp">
<head>
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
    <script src="http://code.angularjs.org/1.0.5/angular.min.js"></script>
    <script>
    angular.module('myApp', []).controller('Ctrl', function($scope) {
        $scope.items = [1, 2, 3, 4];
        $scope.reverse = function(array) {
            var copy = [].concat(array);
            return copy.reverse();
        }
    });
    </script>
</head>
<body ng-controller="Ctrl">
    <ul>
        <li ng-repeat="item in items">{{item}}</li>
    </ul>
    <ul>
        <li ng-repeat="item in reverse(items)">{{item}}</li>
    </ul>
</body>
</html>

โปรดทราบว่าการ$scope.reverseสร้างสำเนาของอาร์เรย์ตั้งแต่Array.prototype.reverseปรับเปลี่ยนอาร์เรย์เดิม


13

หากคุณใช้ 1.3.x คุณสามารถใช้สิ่งต่อไปนี้

{{ orderBy_expression | orderBy : expression : reverse}}

ตัวอย่างรายการหนังสือตามวันที่ตีพิมพ์เรียงตามลำดับจากมากไปน้อย

<div ng-repeat="book in books|orderBy:'publishedDate':true">

แหล่งที่มา: https://docs.angularjs.org/api/ng/filter/orderBy



1

เมื่อใช้ MVC ใน. NET กับ Angular คุณสามารถใช้ OrderByDecending () เมื่อทำแบบสอบถาม db ของคุณเช่นนี้:

var reversedList = dbContext.GetAll().OrderByDecending(x => x.Id).ToList();

จากนั้นทางด้าน Angular จะถูกย้อนกลับในเบราว์เซอร์บางตัว (IE) เมื่อรองรับ Chrome และ FF คุณจะต้องเพิ่มคำสั่งซื้อโดย:

<tr ng-repeat="item in items | orderBy:'-Id'">

ในตัวอย่างนี้คุณจะเรียงลำดับจากมากไปน้อยในคุณสมบัติ. ID หากคุณกำลังใช้เพจจิ้งสิ่งนี้จะซับซ้อนมากขึ้นเพราะจะมีการเรียงหน้าแรกเท่านั้น คุณจะต้องจัดการสิ่งนี้ผ่านไฟล์ตัวกรอง. js สำหรับคอนโทรลเลอร์ของคุณหรือด้วยวิธีอื่น


0

คุณยังสามารถใช้. reverse () มันเป็นฟังก์ชั่นอาร์เรย์แบบเนทีฟ

<div ng-repeat="friend in friends.reverse()">{{friend.name}}</div>


การลงคะแนนของคุณสามารถหมายถึงสิ่งเดียวเท่านั้น: คุณมีข้อมูลที่เข้ามามากขึ้น หาก {} หรือ [] ยังคงได้รับข้อมูลมันจะย้อนกลับทุกครั้งอย่างชัดเจน เป็นการย่อยใหม่
Pian0_M4n

คำเตือนสำหรับผู้ที่ต้องการใช้สิ่งนี้: reverseย้อนกลับอาร์เรย์ในสถานที่มันไม่เพียงแค่ส่งคืนสำเนาที่ตรงกันข้าม ซึ่งหมายความว่าทุกครั้งที่มีการประเมินค่าอาร์เรย์จะถูกย้อนกลับ
jcaron

0

นั่นเป็นเพราะคุณกำลังใช้ JSON Object เมื่อคุณประสบปัญหาดังกล่าวให้เปลี่ยนวัตถุ JSON เป็นวัตถุอาร์เรย์ JSON

ตัวอย่างเช่น,

{"India":"IN","America":"US","United Kingdon":"UK"} json object
[{"country":"India","countryId":"IN"},{"country":"America","countryId":"US"},{"country":"United Kingdon","countryId":"UK"}] 

0

orderByกรองดำเนินการมีเสถียรภาพการเรียงลำดับณ 1.4.5 เชิงมุม (ดูคำขอดึงข้อมูล GitHub https://github.com/angular/angular.js/pull/12408 )

ดังนั้นจึงเพียงพอที่จะใช้เพรดิเคตคงที่และreverseตั้งค่าเป็นtrue:

<div ng-repeat="friend in friends | orderBy:0:true">{{friend.name}}</div>

0

ฉันพบสิ่งนี้ แต่แทนที่จะใช้อาร์เรย์ฉันใช้วัตถุ

นี่คือวิธีแก้ปัญหาของฉันสำหรับวัตถุ:

เพิ่มตัวกรองที่กำหนดเอง:

app.filter('orderObjectBy', function() {
    return function(items, field, reverse){

        var strRef = function (object, reference) {
            function arr_deref(o, ref, i) {
                return !ref ? o : (o[ref.slice(0, i ? -1 : ref.length)]);
            }
            function dot_deref(o, ref) {
                return !ref ? o : ref.split('[').reduce(arr_deref, o);
            }
            return reference.split('.').reduce(dot_deref, object);
        };

        var filtered = [];

        angular.forEach(items, function(item) {
           filtered.push(item);
        });
        filtered.sort(function (a, b) {
           return (strRef(a, field) > strRef(a, field) ? 1 : -1);
        });
        if(reverse) filtered.reverse();
        return filtered;
    };
});

ซึ่งสามารถใช้งานได้เช่น

<div ng-repeat="(key, value) in items | orderObjectBy:'field.any.deep':true">

หากคุณต้องการการสนับสนุนเบราว์เซอร์รุ่นเก่าคุณจะต้องกำหนดฟังก์ชั่นลดขนาด (มีเฉพาะใน ECMA-262 mozilla.org เท่านั้น )

// Production steps of ECMA-262, Edition 5, 15.4.4.21
// Reference: http://es5.github.io/#x15.4.4.21
if (!Array.prototype.reduce) {
Array.prototype.reduce = function(callback /*, initialValue*/) {
'use strict';
  if (this == null) {
    throw new TypeError('Array.prototype.reduce called on null or undefined');
  }
  if (typeof callback !== 'function') {
    throw new TypeError(callback + ' is not a function');
  }
  var t = Object(this), len = t.length >>> 0, k = 0, value;
  if (arguments.length == 2) {
    value = arguments[1];
  } else {
    while (k < len && !(k in t)) {
      k++; 
    }
    if (k >= len) {
      throw new TypeError('Reduce of empty array with no initial value');
    }
    value = t[k++];
  }
  for (; k < len; k++) {
    if (k in t) {
      value = callback(value, t[k], k, t);
    }
  }
  return value;
};
}

0

ฉันรู้สึกหงุดหงิดกับปัญหานี้ด้วยตัวเองดังนั้นฉันจึงแก้ไขตัวกรองที่สร้างโดย @Trevor Senior เนื่องจากฉันพบปัญหากับคอนโซลของฉันโดยบอกว่ามันไม่สามารถใช้วิธีการย้อนกลับได้ ฉันยังต้องการที่จะรักษาความสมบูรณ์ของวัตถุเพราะนี่คือสิ่งที่ Angular ใช้ในการสั่งซ้ำ ng ในกรณีนี้ฉันใช้อินพุตของ stupid (คีย์) เนื่องจากคอนโซลจะอารมณ์เสียโดยบอกว่ามีรายการที่ซ้ำกันและในกรณีของฉันฉันต้องติดตามโดย $ index

กรอง:

angular.module('main').filter('reverse', function() {
    return function(stupid, items) {
    var itemss = items.files;
    itemss = itemss.reverse();  
    return items.files = itemss; 
  };
});

HTML: <div ng-repeat="items in items track by $index | reverse: items">


0

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


0

เคล็ดลับที่เป็นประโยชน์:

คุณสามารถกลับรายการอาร์เรย์ด้วยวานิลลา Js: yourarray .reverse ()

ข้อควรระวัง: reverse เป็นอันตรายดังนั้นมันจะเปลี่ยนอาร์เรย์ของคุณไม่เพียง แต่ตัวแปร


-2

ฉันจะใช้อาร์เรย์ sugest $indexวิธีการย้อนกลับพื้นเมืองทางเลือกที่ดีกว่าเสมอสร้างตัวกรองหรือใช้

<div ng-repeat="friend in friends.reverse()">{{friend.name}}</div>

Plnkr_demo


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