【问题标题】:sorting values of a hash object in ngRepeat - angularJS在ngRepeat中对哈希对象的值进行排序 - angularJS
【发布时间】:2012-11-25 15:23:45
【问题描述】:

我有一个这样的对象:

$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>

【问题讨论】:

    标签: object hash angularjs


    【解决方案1】:

    虽然 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;
      };
    });
    

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

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

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

    【讨论】:

    • 您博客文章中的代码不起作用,而这个代码却……奇怪:)谢谢老兄,救了我的命!
    【解决方案2】:

    如果您检查documentation,它表示 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>
    

    【讨论】:

      【解决方案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。

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

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

      【讨论】:

        【解决方案4】:

        首先,您需要了解ng:filterng:orderBy 与数组(项的有序集合)一起使用,但您尝试在对象(_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>
        

        【讨论】:

          猜你喜欢
          • 2013-08-10
          • 1970-01-01
          • 1970-01-01
          • 2015-10-23
          • 1970-01-01
          • 2011-03-10
          • 1970-01-01
          • 2015-01-01
          • 2012-03-31
          相关资源
          最近更新 更多