最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - AngularJS - How to order ng-repeat using another array - Stack Overflow

programmeradmin1浏览0评论

Say I have an array of keys in a specific order

orderedNames=["mike","bob","sarah];

and I have a JSON that I want to show using ng-repeat but in the order that they appear in the array:

{"people":
    {
    "bob":{
        "hair":"brown",
        "eyes":"blue",
        "height":"tall"
        },
    "sarah":{
        "hair":"blonde",
        "eyes":"blue",
        "height":"short"
        }, 
    "mike":{
        "hair":"red",
        "eyes":"blue",
        "height":"tall"
        }
    }
}

How do I write a filer that would cause ng-repeat to spit out the people in the order in which they are specified in the array?

<li ng-repeat="person in people | orderNames"></li>

Say I have an array of keys in a specific order

orderedNames=["mike","bob","sarah];

and I have a JSON that I want to show using ng-repeat but in the order that they appear in the array:

{"people":
    {
    "bob":{
        "hair":"brown",
        "eyes":"blue",
        "height":"tall"
        },
    "sarah":{
        "hair":"blonde",
        "eyes":"blue",
        "height":"short"
        }, 
    "mike":{
        "hair":"red",
        "eyes":"blue",
        "height":"tall"
        }
    }
}

How do I write a filer that would cause ng-repeat to spit out the people in the order in which they are specified in the array?

<li ng-repeat="person in people | orderNames"></li>
Share Improve this question asked Mar 27, 2014 at 19:41 TantelopeTantelope 6171 gold badge10 silver badges24 bronze badges 3
  • Why don't you want to do this in the controller? How are you getting either data (the array with the order and the other with object)? What have you tried? – WagnerMatosUK Commented Mar 27, 2014 at 19:47
  • I'm getting both of those things side by side from the server, the object and the array of keys. Unless there's an easy way to stuff them both into a filter, I'm probably just going to iterate over the array of ids and just get all the data directly from the model using each key rather than using ng-repeat on the object itself. – Tantelope Commented Mar 27, 2014 at 19:55
  • zsong answers sounds like it'd do the trick. I personally still think is better to manipulate the data on the controller as you'll have more control. zsong's answer doesn't guarantee you'll have the data displayed in the order you want. – WagnerMatosUK Commented Mar 27, 2014 at 20:04
Add a ment  | 

4 Answers 4

Reset to default 4

You can define a custom filter.

Plunker: http://plnkr.co/edit/fiuuGoGZK7tM5oefKQlS

index.html

<!DOCTYPE html>
<html ng-app="plunker">

<head>
    <meta charset="utf-8" />
    <title>Filter Example</title>
    <link rel="stylesheet" href="style.css" />
    <script data-require="[email protected]" src="http://code.angularjs/1.2.15/angular.js" data-semver="1.2.15"></script>
    <script src="app.js"></script>
</head>

<body ng-controller="MainCtrl">
<li ng-repeat="person in people|orderNames:orderedNames track by $index">{{person.hair}}</li>
</body>

</html>

app.js:

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

app.controller('MainCtrl', function($scope) {
    $scope.people={
        bob:{
            hair:"brown",
            eyes:"blue",
            height:"tall"
        },
        sarah:{
            hair:"blonde",
            eyes:"blue",
            height:"short"
        },
        mike:{
            hair:"red",
            eyes:"blue",
            height:"tall"
        }
    };
    $scope.orderedNames=["mike","bob","sarah"];

});

app.filter("orderNames",function(){
    return function(input,sortBy) {
        var ordered = [];
        for (var key in sortBy) {
            ordered.push(input[sortBy[key]]);
        }

        return ordered;
    };
});

You could try something like this

<li ng-repeat="name in orderNames">
    {{people[name]}}
</li>

use array as a reference :

http://jsbin./jujoj/14/edit

    $scope.persons = {
   bob:{
     name:'bob'
   },
   mike:{
     name: 'mike'
   },
   sarah: {
     name: 'sarah'
   }
 };

 $scope.orderedNames = [$scope.persons.mike, $scope.persons.bob, $scope.persons.sarah];

HTML : <ul ng-repeat="person in orderedNames"> <li>{{ person.name }}</li> </ul>

to ng-repeat order by another array use

in the controller

$scope.somearray = [1,2,3,4] //or what ever you want to sort by

in the template.

| orderByArray:somearray:true/false

the true/false setting determines if stuff that isn't in the sortby array is outputted after the stuff that is or just dropped.

add the filter

var app = angular.module("app", []).filter("orderByArray", function () {
            return function (input, sortBy, includeOrphans) {
                //sorts by array and returns items with unsorted items at the end if they are not in the sortby array
                if (!angular.isDefined(input)) { return; }
                var ordered = [];
                var remainder = _.cloneDeep(input);
                angular.forEach(sortBy, function (sortitem) {
                    if (angular.isDefined(input[sortitem])) {
                        ordered.push(input[sortitem]);
                        delete (remainder[sortitem]);
                    }
                });
                if (includeOrphans) {
                    angular.forEach(remainder, function (remainingItem, key) {
                        ordered.push(input[key]);
                    });
                }
                return ordered;
            };
        });
发布评论

评论列表(0)

  1. 暂无评论