Kenny Thompson
Kenny Thompson

Reputation: 1492

Angular sorting with nested array

I have been trying to find an answer for a while and have been unable to do so. I was wondering if anyone had an idea on how to sort the following data (members property) within ng-repeat without using a third party tool.

$scope.element = {
    'sortOrder' : '[0].value' // <-- what is wrong? =[
    'members': [
        [
            { 'name' : 'a', 'value' : 'some' },
            { 'name' : 'b', 'value' : 'value' },
            { 'name' : 'c', 'value' : 'another' },
            { 'name' : 'd', 'value' : 'value' }
        ],
        [
            { 'name' : 'a', 'value' : 'other' },
            { 'name' : 'b', 'value' : 'stuff' },
            { 'name' : 'c', 'value' : 'cats' },
            { 'name' : 'd', 'value' : 'reddit' }
        ],
        [
            { 'name' : 'a', 'value' : 'internets' },
            { 'name' : 'b', 'value' : 'bigdata' },
            { 'name' : 'c', 'value' : 'winwin' },
            { 'name' : 'd', 'value' : 'himom' }
        ]
    ]
}

So, the above data is essentially representing a table. The data can't be restructured for various reasons. Right now I have the following as my markup:

<table class="table">
    <thead>
        <tr>
            <th ng-repeat="key in element.members[0]">
                <a href="#" ng-click="element.sortOrder = '[' + $index + ']' + '.value'">{{ key.name }}</a>
            </th>
        </tr>
    </thead>
    <tbody>
        <tr ng-repeat="subelement in element.members | orderBy : element.sortOrder">
            <td ng-repeat="element in subelement" ng-include src="template(element, true)">
            </td>
        </tr>
    </tbody>
</table>

The sortOrder property looks like... it could be correct? I looked at other examples where people had to do this sort of thing (they were using named properties instead of indexes) and I thought I might be getting somewhere, but to no avail.

Any words of enlightenment would be appreciated. Thanks!

Upvotes: 0

Views: 1470

Answers (1)

Ye Liu
Ye Liu

Reputation: 8976

You can't use [0].value with orderBy, the string used with orderBy should be a property of the objects you want to sort. In your case, you want to sort an array of arrays, but [0].value isn't a property of an array, so your approach doesn't work.

However, orderBy can take a "Getter" function to get a value from the object you're sorting, so you can utilize it as follow:

Controller:

$scope.element = {
    sortOrder: -1, // sortOrder is the index, -1 = unsorted
    members: [...]
};

$scope.getValue = function(member) {
    if ($scope.element.sortOrder < 0) {
        return null; // keep members being unsorted
    }
    return member[$scope.element.sortOrder].value;
};

Template:

<table class="table">
    <thead>
        <tr>
            <th ng-repeat="key in element.members[0]">
                <a href="#" ng-click="element.sortOrder = $index">{{ key.name }}</a>
            </th>
        </tr>
    </thead>
    <tbody>
        <tr ng-repeat="subelement in element.members | orderBy : getValue">
            <td ng-repeat="element in subelement" ng-include src="template(element, true)">
            </td>
        </tr>
    </tbody>
</table>

Here is an working plunk for you to play with: http://plnkr.co/edit/bebYBCoa6zptOHNLVL9X

Upvotes: 1

Related Questions