góc ng-lặp lại theo chiều ngược lại


227

Làm thế nào tôi có thể có được một mảng đảo ngược trong góc? Tôi đang cố gắng sử dụng bộ lọc orderBy, nhưng nó cần một vị ngữ (ví dụ: 'name') để sắp xếp:

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

Có cách nào để đảo ngược mảng ban đầu, mà không cần sắp xếp. như thế

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


@QuiteNoth Đó là cách đúng đắn nếu bạn muốn đảo ngược một mảng bằng một biểu thức. Trong trường hợp này, câu hỏi là làm thế nào để hoàn nguyên một mảng mà không có một mảng .
JayQuerie.com

<tr ng-repeat = "friend in friends | orderBy: '- name'">
desmati

Xem câu trả lời của tôi dưới đây cho 1 dòng đơn giản và giải pháp chính xác. Không cần thực hiện bất kỳ phương pháp nào. Tôi tự hỏi tại sao mọi người đang làm phương pháp bổ sung cho việc này.
Muhammad Hassam

Luôn sử dụng các bộ lọc để thay đổi ng-repeathành vi! @Trevor Senior đã làm rất tốt.
Amir Savand

Câu trả lời:


329

Tôi sẽ đề nghị sử dụng bộ lọc tùy chỉnh như thế này:

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

Mà sau đó có thể được sử dụng như:

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

Xem nó hoạt động ở đây: Trình diễn Plunker


Bộ lọc này có thể được tùy chỉnh để phù hợp với nhu cầu của bạn khi thấy phù hợp. Tôi đã cung cấp các ví dụ khác trong cuộc biểu tình. Một số tùy chọn bao gồm kiểm tra biến đó là một mảng trước khi thực hiện ngược lại, hoặc làm cho nó trở nên nhẹ nhàng hơn để cho phép đảo ngược nhiều thứ hơn như chuỗi.


21
Đẹp! Chỉ cần lưu ý rằng items.reverse()sửa đổi mảng thay vì chỉ tạo một cái mới và trả lại nó.
Anders Ekdahl

12
Cảm ơn! Tôi đã bỏ qua điều đó. Tôi đã ném vào một slice()để giải quyết vấn đề đó.
JayQuerie.com

9
Bạn nên thêm if (!angular.isArray(items)) return false;để xác minh rằng bạn có một mảng trước khi cố gắng đảo ngược nó.
tôn trọng TheCode

6
Cần phải phòng thủ nhiều hơn chống lại null, nên sử dụng như sau: trả lại vật phẩm? mục.slice (). Reverse (): [];
Chris Yeung

5
@Chris Yeung: Không nên trả lại "[]" trống khi null. Tốt hơn để trả về giá trị ban đầu.
Siva

202

Đây là những gì tôi đã sử dụng:

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

Cập nhật:

Câu trả lời của tôi là OK cho phiên bản cũ của Angular. Bây giờ, bạn nên sử dụng

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

hoặc là

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

từ https://stackoverflow.com/a/26635708/1782470


Uing track by, đây là cách duy nhất hiệu quả với tôi

@delboud bạn nên sử dụng theo dõi sau khi đặt ng-repeat="friend in friends | orderBy:'+': true track by $index"
hàngBy

125

Xin lỗi vì đã đưa ra điều này sau một năm, nhưng có một giải pháp mới, dễ dàng hơn , hoạt động cho Angular v1.3.0-rc.5 trở lên .

Nó được đề cập trong các tài liệu : "Nếu không có thuộc tính nào được cung cấp, (ví dụ '+') thì chính phần tử mảng được sử dụng để so sánh nơi sắp xếp". Vì vậy, giải pháp sẽ là:

ng-repeat="friend in friends | orderBy:'-'" hoặc là

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

Giải pháp này có vẻ tốt hơn vì nó không sửa đổi một mảng và không yêu cầu tài nguyên tính toán bổ sung (ít nhất là trong mã của chúng tôi). Tôi đã đọc tất cả các câu trả lời hiện có và vẫn thích câu trả lời này cho họ.


1
Cảm ơn vì tiền hỗ trợ! Là một người đứng đầu cho bất kỳ ai khác đọc nó, có vẻ như điều này không hoạt động trong RC4 ( v1.3.0-rc.4). Nếu bất cứ ai có cơ hội dùng thử trong phiên bản mới, hãy cho chúng tôi biết!
mikermcneil

1
@mikermcneil Cảm ơn bạn đã bình luận! Theo cùng một tài liệu, nó sẽ hoạt động bắt đầu từ v1.3.0-rc.5( tài liệu RC.5 so với tài liệu RC.4 ). Tôi đã cập nhật câu trả lời
Dmitry Gonchar

1
Không làm việc cho tôi (v1.3.5). Cố gắng orderBy:'+':true, orderBy:'-':true, orderBy:'-':false, orderBy:'+':false:(
Cody

2
@Cody Xin lỗi vì câu trả lời muộn. Ở đây bạn đi - một ví dụ hoạt động với góc v1.3.5 jsfiddle.net/dmitry_gonchar/L98foxhm/1 . Có lẽ vấn đề là ở một nơi khác.
Dmitry Gonchar

1
@alevkon Đúng. Nhưng nó hoạt động nếu bạn chỉ định trường ('+ id', '-id' fe). Có lẽ đây là một lỗi trong Angular, rằng nó không hoạt động với thứ tự bình thường nếu bạn không chỉ định một trường? Tôi lấy phương pháp này từ các tài liệu (liên kết nằm trong câu trả lời), vì vậy tôi cũng ngạc nhiên như bạn. Dù sao, câu hỏi là làm thế nào để đảo ngược một mảng.
Dmitry Gonchar

54

Bạn có thể đảo ngược bởi tham số $ index

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

13
Nên hoạt động, nhưng không (cố gắng có và không có trích dẫn xung quanh $index). Tôi đang ở góc 1.1.5.
Kỹ sư

2
Đã làm việc cho tôi (đang sử dụng một thuộc tính để sắp xếp thay vì $ index) stackoverflow.com/questions/16261348/
Kẻ

4
Không hoạt động với AngularJS 1.2.13. Tôi đã sửa đổi mảng đối tượng của mình để thêm id vào từng đối tượng. Id là chỉ mục của đối tượng bên trong mảng. Sau đó ng-repeat="friend in friends | orderBy:'id':true"hoạt động.
tanguy_k

51

Giải pháp đơn giản: - (không cần thực hiện bất kỳ phương pháp nào)

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

2
Hoạt động tốt cho tôi. Cảm ơn!
HankScorpio

17

Bạn chỉ có thể gọi một phương thức trên phạm vi của mình để đảo ngược nó cho bạn, như thế này:

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

Lưu ý rằng việc $scope.reversetạo một bản sao của mảng kể từ khi Array.prototype.reversesửa đổi mảng ban đầu.


13

nếu bạn đang sử dụng 1.3.x, bạn có thể sử dụng như sau

{{ orderBy_expression | orderBy : expression : reverse}}

Ví dụ Liệt kê sách theo ngày xuất bản theo thứ tự giảm dần

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

nguồn: https://docs.angularjs.org/api/ng/filter/orderBy


11

Nếu bạn đang sử dụng angularjs phiên bản 1.4.4 trở lên , một cách dễ dàng để sắp xếp là sử dụng " $ index ".

 <ul>
  <li ng-repeat="friend in friends|orderBy:$index:true">{{friend.name}}</li>
</ul>

xem bản demo


1

Khi sử dụng MVC trong .NET với Angular, bạn luôn có thể sử dụng OrderByDecending () khi thực hiện truy vấn db của mình như sau:

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

Sau đó, về phía Angular, nó sẽ bị đảo ngược trong một số trình duyệt (IE). Khi hỗ trợ Chrome và FF, sau đó bạn sẽ cần thêm orderBy:

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

Trong ví dụ này, bạn sẽ sắp xếp theo thứ tự giảm dần trên thuộc tính .Id. Nếu bạn đang sử dụng phân trang, điều này sẽ phức tạp hơn vì chỉ có trang đầu tiên được sắp xếp. Bạn cần xử lý việc này thông qua tệp bộ lọc .js cho bộ điều khiển của bạn hoặc theo một cách khác.


0

Bạn cũng có thể sử dụng .reverse (). Đây là một hàm mảng riêng

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


Việc bạn bỏ phiếu chỉ có thể có một ý nghĩa: bạn có nhiều dữ liệu đến hơn. Nếu {} hoặc [] tiếp tục nhận dữ liệu, rõ ràng nó sẽ đảo ngược mỗi lần. Đó là một thông báo mới
Pian0_M4n

Cảnh báo cho bất cứ ai muốn sử dụng điều này: reverseđảo ngược mảng tại chỗ, nó không chỉ trả lại một bản sao đảo ngược. Điều này có nghĩa là mỗi khi điều này được đánh giá, mảng sẽ bị đảo ngược.
jcaron

0

Đó là bởi vì bạn đang sử dụng JSON Object. Khi bạn gặp phải những vấn đề như vậy thì hãy thay đổi Đối tượng JSON của bạn thành Đối tượng mảng JSON.

Ví dụ,

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


0

Tôi tìm thấy một cái gì đó như thế này, nhưng thay vì mảng tôi sử dụng các đối tượng.

Đây là giải pháp của tôi cho các đối tượng:

Thêm bộ lọc tùy chỉnh:

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

Mà sau đó có thể được sử dụng như

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

Nếu bạn cần hỗ trợ trình duyệt cũ, bạn sẽ cần xác định chức năng giảm (điều này chỉ khả dụng trong 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

Tôi đã cảm thấy thất vọng với vấn đề này và vì vậy tôi đã sửa đổi bộ lọc được tạo bởi @Trevor Senior khi tôi gặp vấn đề với bảng điều khiển của mình nói rằng nó không thể sử dụng phương pháp ngược. Tôi cũng muốn giữ tính toàn vẹn của đối tượng bởi vì đây là những gì Angular ban đầu sử dụng trong một lệnh ng-repeat. Trong trường hợp này, tôi đã sử dụng đầu vào của ngu ngốc (khóa) vì bảng điều khiển sẽ khó chịu khi nói rằng có các bản sao và trong trường hợp của tôi, tôi cần theo dõi bằng $ index.

Bộ lọc:

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

Tôi thêm một câu trả lời mà không ai đề cập. Tôi sẽ cố gắng làm cho máy chủ làm điều đó nếu bạn có. Lọc khách hàng có thể nguy hiểm nếu máy chủ trả về nhiều hồ sơ. Bởi vì bạn có thể bị buộc phải thêm phân trang. Nếu bạn đã phân trang từ máy chủ thì bộ lọc máy khách theo thứ tự, sẽ ở trang hiện tại. Mà sẽ gây nhầm lẫn cho người dùng cuối. Vì vậy, nếu bạn có một máy chủ, sau đó gửi orderby với cuộc gọi và để máy chủ trả lại nó.


0

Lời khuyên hữu ích:

Bạn có thể đảo ngược mảng của bạn với vanilla Js: yourarray .reverse ()

Chú ý: đảo ngược là phá hoại, vì vậy nó sẽ thay đổi mảng của bạn, không chỉ là biến.


-2

Tôi sẽ sử dụng phương pháp đảo ngược mảng gốc luôn là lựa chọn tốt hơn so với việc tạo bộ lọc hoặc sử dụng $index.

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

Plnkr_demo .


Bạn đang đảo ngược mảng ban đầu ... Một cách tốt hơn là trả về một mảng mới được đảo ngược.
Vandervidi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.