【问题标题】:Angular - Can't make ng-repeat orderBy workAngular - 无法使 ng-repeat orderBy 工作
【发布时间】:2013-10-23 15:08:43
【问题描述】:

我用 orderBy 尝试了很多 ng-repeat 的例子,但我无法让我的 json 使用它。

<div ng-app>
    <script type="text/javascript" src="http://code.angularjs.org/1.0.1/angular-1.0.1.js"></script>
    <div ng:controller="Main">
        <div ng-repeat="release in releases| orderBy:'environment_id'">      
            {{release.environment_id}}
        </div>
    </div>
</div>

还有 JSON

function Main($scope) {
$scope.releases = {
    "tvl-c-wbap001 + tvl-webapp": {
        "timestamp": " 05:05:53 PM ",
        "environment_id": "CERT5",
        "release_header": "Projects/Dev",
        "date": "19 Oct",
        "release": "12.11.91-1"
    },
    "tvl-c-wbap401 + tvl-webapp": {
        "timestamp": " 10:07:25 AM ",
        "environment_id": "CERT4",
        "release_header": "Future Release",
        "date": "15 Oct",
        "release": "485-1"
    },
    "tvl-c-wbap301 + tvl-webapp": {
        "timestamp": " 07:59:48 AM ",
        "environment_id": "CERT3",
        "release_header": "Next Release",
        "date": "15 Oct",
        "release": "485-1"
    },
    "tvl-c-wbap201 + tvl-webapp": {
        "timestamp": " 03:34:07 AM ",
        "environment_id": "CERT2",
        "release_header": "Next Changes",
        "date": "15 Oct",
        "release": "13.12.3-1"
    },
    "tvl-c-wbap101 + tvl-webapp": {
        "timestamp": " 12:44:23 AM ",
        "environment_id": "CERT1",
        "release_header": "Production Mirror",
        "date": "15 Oct",
        "release": "13.11.309-1"
    },
    "tvl-s-wbap002 + tvl-webapp": {
        "timestamp": " 12:43:23 AM ",
        "environment_id": "Stage2",
        "date": "15 Oct",
        "release": "13.11.310-1"
    },
    "tvl-s-wbap001 + tvl-webapp": {
        "timestamp": " 11:07:38 AM ",
        "environment_id": "Stage1",
        "release_header": "Production Mirror",
        "date": "11 Oct",
        "release": "13.11.310-1"
    },
    "tvl-p-wbap001 + tvl-webapp": {
        "timestamp": " 11:39:25 PM ",
        "environment_id": "Production",
        "release_header": "Pilots",
        "date": "14 Oct",
        "release": "13.11.310-1"
    },
    "tvl-p-wbap100 + tvl-webapp": {
        "timestamp": " 03:27:53 AM ",
        "environment_id": "Production",
        "release_header": "Non Pilots",
        "date": "11 Oct",
        "release": "13.11.309-1"
    }
}

不管我写什么,我总是得到相同的订单,或者我可能会说,根本没有订单。

【问题讨论】:

    标签: javascript json angularjs angularjs-ng-repeat


    【解决方案1】:

    orderBy 仅适用于数组 -- 请参阅 http://docs.angularjs.org/api/ng.filter:orderBy

    也是一个很好的过滤器,用于对象而不是数组@Angularjs OrderBy on ng-repeat doesn't work

    【讨论】:

    • 我有一个数组,但这在 Chrome 中不起作用。你知道为什么吗?
    【解决方案2】:

    您将不得不将您的发布对象重新格式化为对象的数组。然后您就可以按照您尝试的方式对它们进行排序。

    【讨论】:

      【解决方案3】:

      如前所述,只允许使用数组。但是为了简单起见,您可以通过管道函数将对象动态转换为数组,如此处所示 https://gist.github.com/brev/3949705

      只需声明过滤器,并将其添加到 ng-repeat :)

      <div ng-app="myApp">
      <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
      <div ng-controller="Main">
        <div ng-repeat="release in releases | object2Array | orderBy:'environment_id'">{{release.environment_id}}</div>
      </div>
      
      <script>
      
      var app = angular.module('myApp', []).filter('object2Array', function() {
          return function(input) {
            var out = []; 
            for(i in input){
              out.push(input[i]);
            }
            return out;
          }
        })
      .controller('Main',function ($scope) {
              $scope.releases = {"tvl-c-wbap001 + tvl-webapp":{"timestamp":" 05:05:53 PM ","environment_id":"CERT5","release_header":"Projects/Dev","date":"19 Oct","release":"12.11.91-1"},"tvl-c-wbap401 + tvl-webapp":{"timestamp":" 10:07:25 AM ","environment_id":"CERT4","release_header":"Future Release","date":"15 Oct","release":"485-1"},"tvl-c-wbap301 + tvl-webapp":{"timestamp":" 07:59:48 AM ","environment_id":"CERT3","release_header":"Next Release","date":"15 Oct","release":"485-1"},"tvl-c-wbap201 + tvl-webapp":{"timestamp":" 03:34:07 AM ","environment_id":"CERT2","release_header":"Next Changes","date":"15 Oct","release":"13.12.3-1"},"tvl-c-wbap101 + tvl-webapp":{"timestamp":" 12:44:23 AM ","environment_id":"CERT1","release_header":"Production Mirror","date":"15 Oct","release":"13.11.309-1"},"tvl-s-wbap002 + tvl-webapp":{"timestamp":" 12:43:23 AM ","environment_id":"Stage2","date":"15 Oct","release":"13.11.310-1"},"tvl-s-wbap001 + tvl-webapp":{"timestamp":" 11:07:38 AM ","environment_id":"Stage1","release_header":"Production Mirror","date":"11 Oct","release":"13.11.310-1"},"tvl-p-wbap001 + tvl-webapp":{"timestamp":" 11:39:25 PM ","environment_id":"Production","release_header":"Pilots","date":"14 Oct","release":"13.11.310-1"},"tvl-p-wbap100 + tvl-webapp":{"timestamp":" 03:27:53 AM ","environment_id":"Production","release_header":"Non Pilots","date":"11 Oct","release":"13.11.309-1"}}
          });
      </script>
      

      【讨论】:

      • 我使用更简单的toArray 过滤器:function(obj){return Object.keys(obj).map(function(key){return obj[key];});}
      • 太棒了……太棒了。感谢您发布此信息。大有帮助!
      • 我不确定过滤器是否会发生这种情况,但是如果您使用函数在每个排序上创建一个数组,则 $digest 会多次触发。谁能告诉这是否也使用过滤器发生?见docs.angularjs.org/error/$rootScope/infdig
      • 难道现在orderBy不仅支持数组吗? De doc 链接声明:“还支持类似数组的值(例如 NodeLists、jQuery 对象、TypedArrays、字符串等)。”
      【解决方案4】:

      在上面 Eike Thies 的回复中,如果我们使用 underscore.js,过滤器可以简化为:

      var app = angular.module('myApp', []).filter('object2Array', function() {
        return function(input) {
          return _.toArray(input);
        }
      });
      

      【讨论】:

      • 迄今为止最好的答案!太棒了。
      【解决方案5】:

      迭代对象时,内置 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;
        };
      });
      
      <ul>
      <li ng-repeat="item in items | orderObjectBy:'color':true">{{ item.color }}</li>
      </ul>
      

      【讨论】:

        【解决方案6】:

        这是@Julian Mosquera 的代码的一个版本,它也支持按对象key排序:

        yourApp.filter('orderObjectBy', function () {
            return function (items, field, reverse) {
                // Build array
                var filtered = [];
                for (var key in items) {
                    if (field === 'key')
                        filtered.push(key);
                    else
                        filtered.push(items[key]);
                }
                // Sort array
                filtered.sort(function (a, b) {
                    if (field === 'key')
                        return (a > b ? 1 : -1);
                    else
                        return (a[field] > b[field] ? 1 : -1);
                });
                // Reverse array
                if (reverse)
                    filtered.reverse();
                return filtered;
            };
        });
        

        【讨论】:

          【解决方案7】:

          orderby 适用于包含具有可用作过滤器的即时值的对象的数组,即

          controller.images = [{favs:1,name:"something"},{favs:0,name:"something else"}];
          

          当上述数组重复时,可以使用 | orderBy:'favs' 直接引用该值,或在前面使用减号以降序

          <div class="timeline-image" ng-repeat="image in controller.images | orderBy:'-favs'">
              <img ng-src="{{ images.name }}"/>
          </div>
          

          【讨论】:

            【解决方案8】:

            这是@Julian Mosquera 的代码的一个版本,它还支持在主字段为空或未定义的情况下使用“后备”字段:

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

            【讨论】:

              猜你喜欢
              • 2015-01-07
              • 2016-01-26
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-06-18
              • 1970-01-01
              • 1970-01-01
              • 2015-02-11
              相关资源
              最近更新 更多