Skip ng-repeat JSON ordering in Angular JS

2019-01-07 16:54发布

Does anybody know how I can SKIP JSON ordering altogether when I use ng-repeat (in a painless way probably)?

For example, my source JSON looks something like this -

{
   "title": "Title",
   "description": "Description",
   "moreInfo": "Moreinformation"
}

Once I use it in ng-repeat, it orders them alphabetically. Something like this -

{
   "description": "Description",
   "moreInfo": "Moreinformation",
   "title": "Title"
}

My ng-repeat looks something like this -

<div ng-repeat="(key,data) in items">
   <span class="one"> {{key}} </span>
   <span class="two"> {{data}} </span>
</div>

I've seen people having a separate array of the keys and using them to identify the JSON objects, ultimately avoiding alphabetical sorting.

Is there an elegant way to do this?

4条回答
再贱就再见
2楼-- · 2019-01-07 17:32

At the moment there is no elegant way to do this. Reason being that - ngRepeat creates an associative array, which is called and not the JSON itself. Although the ECMAScript Standard mentions that:

The declaration order of object properties must be preserved, and iteration must happen in the same order.

But somehow, Angular guys overlooked it. This might get rectified in the later releases.

I still think Angular's behaviour makes more sense. As objects often have more initialisation logic around them than arrays, I think it's fair to assume that the order often might not be what the user actually wants/expected, so forcing a specific sorting ensure the proper behaviour - especially when we also have to deal with older browsers.

查看更多
Animai°情兽
3楼-- · 2019-01-07 17:35

I am using this approach to override the alphabetical ordering:

Controller:

$scope.steps = {
    "basic-settings": "Basic Settings",
    "editor": "Editor",
    "preview-and-publish": "Preview & Publish"
};

// NOTE I realise this is a hacky way, but I need to override JS's alphabetical ordering
$scope.stepsKeys = _.keys($scope.steps);

$scope.activeStep = 0;

PLEASE NOTE that _.keys($scope.steps); is LoDash substituting Object.keys();

HTML:

<ul>
    <li ng-repeat="key in stepsKeys" ng-class="{active : stepsKeys[activeStep] == key}">{{ steps[key] }}</li>
</ul>
查看更多
对你真心纯属浪费
4楼-- · 2019-01-07 17:44

Nice workaround found at google groups:

    <div ng-repeat="key in notSorted(data)" ng-init="value = data[key]">
         <pre>
               key: {{key}}
               value: {{value}}
         </pre>           
    </div>

And in scope:

    $scope.data = {
        'key4': 'data4',
        'key1': 'data1',
        'key3': 'data3',
        'key2': 'data2',
        'key5': 'data5'
    };

    $scope.notSorted = function(obj){
        if (!obj) {
            return [];
        }
        return Object.keys(obj);
    }

Working: http://jsfiddle.net/DnEXC/

Original: https://groups.google.com/forum/#!topic/angular/N87uqMfwcTs

查看更多
我欲成王,谁敢阻挡
5楼-- · 2019-01-07 17:56

This answer using filter works best for me.

https://groups.google.com/d/msg/angular/N87uqMfwcTs/EGoY6O2gtzsJ

http://jsfiddle.net/er52h/1/

angular.module('myFilters', [])
  .filter('keys', function() {
    return function(input) {
      if (!input) {
        return [];
      }
      return Object.keys(input);
    }
  });

You can use like this:

<div ng-repeat="key in data | keys" ng-init="value = data[key]"></div>
查看更多
登录 后发表回答