以ng重复 - angularJS排序哈希对象的值

时间:2012-11-25 15:23:45

标签: object hash angularjs

我有一个这样的对象:

$scope.phones = new Object();
$scope.phones['id1'] = {
    "name":"Phone Name1",
    "dateReleased":"2012-1-09 15:48:24"
};
$scope.phones['id2'] = {
    "name": "Phone Name2",
    "dateReleased":"2012-3-12 15:32:11"
};
$scope.phones['id3'] = {
    "name": "Phone Name3",
    "dateReleased":"2012-2-10 13:53:32"
};

我正在使用ngRepeat显示它。我无法按dateReleased订购。此外,反向排序不起作用。我的ngRepeat看起来像这样:

<li ng-repeat="phone in phones | orderBy:dateReleased:true">
    <p>{{phone.name}}</p>
    <p>{{phone.dateReleased}}</p>
</li>

4 个答案:

答案 0 :(得分:12)

虽然ngRepeat可以迭代哈希对象,例如示例中的$scope.phones,但内置的orderBy过滤器将无效。我相信这是由于对象的存储方式。正如其他人所说,你需要将哈希转换为数组。虽然您可以使用上面建议的方法执行此操作,但我更喜欢使用自定义过滤器。这给了我不必直接改变我的哈希的好处,也让我重复使用其他哈希的过滤器。

yourApp.filter('orderObjectBy', function() {
  return function(items, field, reverse) {
    var filtered = [];
    angular.forEach(items, function(item) {
      filtered.push(item);
    });
    filtered.sort(function (a, b) {
      return (a[field] > b[field] ? 1 : -1);
    });
    if(reverse) filtered.reverse();
    return filtered;
  };
});

此过滤器将对象转换为标准数组,并按指定的字段对其进行排序。您可以使用与orderObjectBy完全相同的orderBy过滤器,包括字段名称后面的布尔值,以指定是否应该反转订单。换句话说,false正在升序,true正在降序。

<li ng-repeat="phone in phones | orderObjectBy:'dateReleased':true">
  <p>{{phone.name}}</p>
  <p>{{phone.dateReleased}}</p>
</li>

关于这个话题,我有一个post on my blog

答案 1 :(得分:5)

如果您检查documentation它表示orderBy中的表达式可以是功能,则字符串数组 。因此,您需要 dateReleased 作为字符串:'dateReleased'

此外,你需要你的手机对象是一个真正的阵列。

尝试:

$scope.phones = [{
        "name":"Phone Name1",
        "dateReleased":"2012-1-09 15:48:24"
    },{
        "name": "Phone Name2",
        "dateReleased":"2012-3-12 15:32:11"
    },{
        "name": "Phone Name3",
        "dateReleased":"2012-2-10 13:53:32"
    }];

<li ng-repeat="phone in phones | orderBy:'dateReleased':true">
    <p>{{phone.name}}</p>
    <p>{{phone.dateReleased}}</p>
</li>

答案 2 :(得分:3)

其他两个答案都可以帮助你解决问题,但不是一直......

您需要在示波器上创建一个函数,将对象转换为如下数组:

$scope.phonesArray = function() {
    var result = [];
    angular.forEach($scope.phones, function(phone, id) {
      result.push(phone);
    });
    return result;
};

然后你在ngRepeat中调用它而不是你的对象:

<li ng-repeat="phone in phonesArray() | orderBy:'dateReleased':true">
    <p>{{phone.name}}</p>
    <p>{{phone.dateReleased}}</p>
</li>

另外:请注意'dateReleased'是一个字符串,因此它知道$ eval当前项的字符串,否则它将检查父$ scope.dateReleased,它不存在。< / p>

Here is a plunk for what I think you're trying to do

编辑:你也可以&#34;转换&#34;数组的对象并将其存储在$ scope上,如果您担心这样做的功能过于昂贵而且#34;但这不应该是一个问题,因为您和&#34; #39;为一个用户重新开发一个客户端应用程序,而不是为许多用户开发服务器应用程序,这意味着你有一个小小的摆动空间,而且价格昂贵。#34;。 (无论如何它都胜了)

答案 3 :(得分:2)

首先,您需要了解ng:filterng:orderBy使用Arrays(有序的项集合),但是您尝试在Object上使用它们(_un_ordered项目集合) 。一种可能的方法是将所有对象收集到一个数组中,然后在其上继续使用ng-repeat。像这样:

<ul ng-init="phones = [
      {name:'Phone Name 1', dateReleased:'2011-1-09 15:48:24'}
    , {name:'Phone Name 2', dateReleased:'2012-3-12 15:32:11'}
    , {name:'Phone Name 3', dateReleased:'2012-2-10 13:53:32'}]; 
    pred = '-dateReleased';" >
    <li ng-repeat="phone in phones | orderBy:pred">
        <p>{{phone.name}}</p>
        <p>{{phone.dateReleased}}</p>
    </li>
</ul>