8

我有一个这样的对象:

$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

4 回答 4

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>

我的博客上有一篇关于这个主题的帖子。

于 2013-09-17T19:19:07.830 回答
5

如果您查看文档,它会说 orderBy 中的表达式可以是functionstringArray。因此,您需要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>
于 2012-11-25T18:12:38.547 回答
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。

这是我认为您正在尝试做的事情

编辑:如果您担心这样做的功能太“昂贵”,您也可以将对象“转换”为数组并将其存储在 $scope 上,但这不应该成为问题,因为您为一个用户重新开发客户端应用程序,而不是为许多用户开发服务器应用程序,这意味着您有一点“昂贵”的回旋余地。(反正不会这样)

于 2012-11-27T00:10:39.337 回答
2

首先,您需要了解这一点ng:filterng:orderBy使用数组(项目的有序集合),但您试图在 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>
于 2012-11-25T18:11:20.170 回答