AngularJS 按属性排序

IT技术 javascript angularjs
2021-01-21 01:28:08

我想做的是按属性对一些数据进行排序。这是我认为应该起作用但不起作用的示例。

HTML部分:

<div ng-app='myApp'>
    <div ng-controller="controller">
    <ul>
        <li ng-repeat="(key, value) in testData | orderBy:'value.order'">
            {{value.order}}. {{key}} -> {{value.name}}
        </li>
    </ul>
    </div>
</div>

JS部分:

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

myApp.controller('controller', ['$scope', function ($scope) {

    $scope.testData = {
        C: {name:"CData", order: 1},
        B: {name:"BData", order: 2},
        A: {name:"AData", order: 3},
    }

}]);

结果:

  1. A -> 数据
  2. B -> BData
  3. C -> CData

...恕我直言应该是这样的:

  1. C -> CData
  2. B -> BData
  3. A -> 数据

我错过了什么(这里有准备JSFiddle进行实验)?

6个回答

AngularJS 的 orderBy 过滤器只支持数组——没有对象。所以你必须编写一个自己的小过滤器,为你进行排序。

或者更改您处理的数据格式(如果您对此有影响)。包含对象的数组可按本机 orderBy 过滤器排序。

这是我的 AngularJS 的orderObjectBy过滤器:

app.filter('orderObjectBy', function(){
 return function(input, attribute) {
    if (!angular.isObject(input)) return input;

    var array = [];
    for(var objectKey in input) {
        array.push(input[objectKey]);
    }

    array.sort(function(a, b){
        a = parseInt(a[attribute]);
        b = parseInt(b[attribute]);
        return a - b;
    });
    return array;
 }
});

您认为的用法:

<div class="item" ng-repeat="item in items | orderObjectBy:'position'">
    //...
</div>

在这个例子中,对象需要一个位置属性,但是你可以灵活地使用对象中的任何属性(包含一个整数),只是根据视图中的定义。

示例 JSON:

{
    "123": {"name": "Test B", "position": "2"},
    "456": {"name": "Test A", "position": "1"}
}

这是一个向您展示用法的小提琴:http : //jsfiddle.net/4tkj8/1/

@Wildhoney 这个问题是关于使用键对对象进行排序,而不是包含对象的数组。
2021-03-16 01:28:08
这很棒。我添加了排序 asc/desc 的选项: app.filter('orderObjectBy', function(){ return function(input, attribute, direction) { if (!angular.isObject(input)) return input; var array = [] ; for(var objectKey in input) { array.push(input[objectKey]); } array.sort(function(a, b){ a = parseInt(a[attribute]); b = parseInt(b[attribute]) ; 返回方向 == 'asc' ? a - b : b - a; }); 返回数组; } }); 在 HTML 中:<tr ng-repeat="val in list | orderObjectBy:'prop':'asc'">
2021-03-17 01:28:08
值得一提的是,Angular.js确实在对象的数组现在有一个属性的支持排序:... | orderBy: 'name'
2021-03-25 01:28:08
很好的答案但是我们以这种方式丢失了对象的键。为了保持它,只需添加它在过滤器中创建新数组的行,例如for(var objectKey in input) { input[objectKey]['_key'] = objectKey; array.push(input[objectKey]); }我们可以使用<div ng-repeat="value in object | orderObjectBy:'order'" ng-init="key = value['_key']">
2021-03-26 01:28:08
@Armin 如果这是像数组这样的对象怎么办?IE{1:'Example 1', 2:'Example 2', 3:'Example 3', ...}
2021-04-05 01:28:08

很简单,就这样做吧

$scope.props = [{order:"1"},{order:"5"},{order:"2"}]

ng-repeat="prop in props | orderBy:'order'"
这不适用于关联数组,这就是问题所在。
2021-04-12 01:28:08

不要忘记 parseInt() 仅适用于整数值。要对字符串值进行排序,您需要交换以下内容:

array.sort(function(a, b){
  a = parseInt(a[attribute]);
  b = parseInt(b[attribute]);
  return a - b;
});

有了这个:

array.sort(function(a, b){
  var alc = a[attribute].toLowerCase(),
      blc = b[attribute].toLowerCase();
  return alc > blc ? 1 : alc < blc ? -1 : 0;
});

正如您在 angular-JS ( https://github.com/angular/angular.js/blob/master/src/ng/filter/orderBy.js )的代码中所见,ng-repeat 不适用于对象。这是 sortFunction 的一个技巧。

http://jsfiddle.net/sunnycpp/qaK56/33/

<div ng-app='myApp'>
    <div ng-controller="controller">
    <ul>
        <li ng-repeat="test in testData | orderBy:sortMe()">
            Order = {{test.value.order}} -> Key={{test.key}} Name=:{{test.value.name}}
        </li>
    </ul>
    </div>
</div>

myApp.controller('controller', ['$scope', function ($scope) {

    var testData = {
        a:{name:"CData", order: 2},
        b:{name:"AData", order: 3},
        c:{name:"BData", order: 1}
    };
    $scope.testData = _.map(testData, function(vValue, vKey) {
        return { key:vKey, value:vValue };
    }) ;
    $scope.sortMe = function() {
        return function(object) {
            return object.value.order;
        }
    }
}]);

根据http://docs.angularjs.org/api/ng.filter:orderBy, orderBy 对数组进行排序。在您的情况下,您正在传递一个对象,因此您必须实现自己的排序功能。

或传递一个数组 -

$scope.testData = {
    C: {name:"CData", order: 1},
    B: {name:"BData", order: 2},
    A: {name:"AData", order: 3},
}

看看http://jsfiddle.net/qaK56/

您的 jsfiddle != 您发布的代码。这是您的示例的正确 jsfiddle:jsfiddle.net/qaK56/92
2021-03-17 01:28:08
我知道它适用于数组..所以解决方案是编写我自己的排序函数?
2021-04-08 01:28:08