Angular - 无法使 ng-repeat orderBy 工作
Posted
技术标签:
【中文标题】Angular - 无法使 ng-repeat orderBy 工作【英文标题】:Angular - Can't make ng-repeat orderBy work 【发布时间】: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"
不管我写什么,我总是得到相同的订单,或者我可能会说,根本没有订单。
【问题讨论】:
【参考方案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;
;
);
【讨论】:
以上是关于Angular - 无法使 ng-repeat orderBy 工作的主要内容,如果未能解决你的问题,请参考以下文章
Angular - 无法使用 ng-submit 获取选定的 ng-repeated 单选按钮