39

我正在尝试将 ng-repeat 与字典样式语法一起使用,并将顺序应用于键值。

(key, value) in something | orderBy:'key'

看来 OrderBy 没有按预期工作

这里的例子 http://jsfiddle.net/mhXuW/

4

6 回答 6

19

orderBy 的参数必须与对象数组中的属性名称匹配。

您的数据需要看起来像这样:

$scope.list2 = [ { id:"2013-01-08T00:00:00", name:'Joe'},
                 { id:"2013-01-09T00:00:00", name:'Sue'}];

然后像这样的过滤器将起作用:

<div ng-repeat="item in list2 | orderBy:'id':true">

小提琴

请注意, orderBy 适用于整个数组(something在上面的示例代码中),它返回一个排序数组。keyorderBy 对and一无所知value

于 2013-01-15T05:10:08.280 回答
11

这没有实施。请看这里:

https://github.com/angular/angular.js/issues/1286

编辑(2013 年 8 月 27 日):这个问题现在似乎已经解决了。

于 2013-01-15T04:51:03.950 回答
7

我创建了一个自定义过滤器以使选择列表成为可能:

.filter('toDictionaryArray', function () {
    return function (obj) {
        if (!(obj instanceof Object)) return obj;

        var arr = [];
        for (var key in obj) {
            arr.push({ key: key, value: obj[key] });
        }
        return arr;
    }
})

选择列表 ng-options 的内容如下:

<select ng-options="kv.key as kv.value for kv in p.options | toDictionaryArray | orderBy:'value'"></select>
于 2013-07-11T01:30:25.433 回答
2

正如 akonsu 所说,这里已经请求了该功能。但是,我仍然无法让它与最新的 (1.3.0) 测试版一起使用。

评论中有一个很好的解决方法(请注意,这需要下划线,并且您必须在上面的示例中用 'value.$key' 替换对 'key' 的引用):

[添加过滤器]:

app.filter('toArray', function() { return function(obj) {
    if (!(obj instanceof Object)) return obj;
    return _.map(obj, function(val, key) {
        return Object.defineProperty(val, '$key', {__proto__: null, value: key});
    });
}});

示例标记:

<div ng-repeat="val in object | toArray | orderBy:'priority' | filter:fieldSearch">
  {{val.$key}} : {{val}} 
</div>

潜在的缺点:

  • Object.defineProperty 在 IE8 中不会像这样工作(如果您不介意使 $key 可枚举,那么这是一个简单的更改)。
  • 如果您的属性值不是对象,那么您不能设置 $key 属性,这将失败。
  • 它没有直接集成到 orderBy 或 ngRepeat 中,因此语法不同。
于 2014-07-14T15:51:28.513 回答
2

这是一个很好的解决方法(angular-toArrayFilter):

.filter('toArray', function () {
  return function (obj, addKey) {
    if ( addKey === false ) {
      return Object.keys(obj).map(function(key) {
        return obj[key];
      });
    } else {
      return Object.keys(obj).map(function (key) {
        if(typeof obj[key] == 'object') return Object.defineProperty(obj[key], '$key', {     enumerable: false, value: key});
      });
    }
  };
});
于 2014-08-19T18:57:58.873 回答
0

而不是使用仅支持数组而不支持对象的 orderby 过滤器。您可以像这样编写自己的过滤器,我从 Justin Klemm http://justinklemm.com/angularjs-filter-ordering-objects-ngrepeat/获取代码,并添加了对指定多个排序字段的支持。下面的过滤器示例是基于值中的属性进行过滤,但您也可以轻松地将其更改为基于键进行过滤。

app.filter('orderObjectBy', function()
{
    return function(items, fields, reverse)
    {
        var filtered = [];
        angular.forEach(items, function(item)
        {
            filtered.push(item);
        });

        filtered.sort(function (a, b)
        {
            var result = 0;

            for (var i = 0; i < fields.length; ++i)
            {
                if (a[fields[i]] > b[fields[i]])
                {
                    result = 1;
                    break;
                }
                else if (a[fields[i]] < b[fields[i]])
                {
                    result = -1;
                    break;
                }
            }

            return result;
        });

        if (reverse)
        {
            filtered.reverse();
        }

        return filtered;
    };
});

然后在您的 html5 网页中使用它,其中统计数据是带有键值对的地图/字典。

<div class="row" ng-repeat="stat in statistics | orderObjectBy: 'NumTimesPartnered', 'NumTimesOpponent']:true">
    <div class="col col-33">{{stat.Name}}</div>
    <div class="col"><center>{{stat.NumTimesPartnered}}</center></div>
    <div class="col"><center>{{stat.NumTimesOpponent}}</center></div>
</div>
于 2015-03-05T00:32:35.603 回答