admin管理员组

文章数量:1022688

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

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

本文标签: javascriptAngularJSHow to order ngrepeat using another arrayStack Overflow