Javascript Orderby 无法在 ng-repeat 上使用 dict 语法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14330878/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Orderby not working with dict syntax on ng-repeat
提问by Cameron Singe
I am trying to use ng-repeat with a dictionary style syntax and apply an order to the key value.
我正在尝试将 ng-repeat 与字典样式语法一起使用,并将顺序应用于键值。
(key, value) in something | orderBy:'key'
(key, value) in something | orderBy:'key'
It seems OrderBy isn't working as expected
OrderBy 似乎没有按预期工作
Example here http://jsfiddle.net/mhXuW/
采纳答案by Mark Rajcok
The parameters to orderBy must match property names in an array of objects.
orderBy 的参数必须与对象数组中的属性名称匹配。
Your data needs to look something like this:
您的数据需要如下所示:
$scope.list2 = [ { id:"2013-01-08T00:00:00", name:'Joe'},
{ id:"2013-01-09T00:00:00", name:'Sue'}];
Then a filter like this will work:
然后像这样的过滤器将起作用:
<div ng-repeat="item in list2 | orderBy:'id':true">
小提琴。
Note that orderBy works on the entire array (somethingin your sample code above) and it returns a sorted array. orderBy doesn't know anything about keyand value.
请注意, orderBy 适用于整个数组(something在上面的示例代码中)并返回一个排序的数组。orderBy 对keyand一无所知value。
回答by akonsu
this is not implemented. please see here:
这没有实施。请看这里:
https://github.com/angular/angular.js/issues/1286
https://github.com/angular/angular.js/issues/1286
EDIT (Aug 27, 2013): this issue seems to be resolved now.
编辑(2013 年 8 月 27 日):这个问题现在似乎已经解决了。
回答by Peter Riesz
I created a custom filter to make this possible for a select list:
我创建了一个自定义过滤器,使选择列表成为可能:
.filter('toDictionaryArray', function () {
return function (obj) {
if (!(obj instanceof Object)) return obj;
var arr = [];
for (var key in obj) {
arr.push({ key: key, value: obj[key] });
}
return arr;
}
})
the select list ng-options then reads as follows:
选择列表 ng-options 然后如下所示:
<select ng-options="kv.key as kv.value for kv in p.options | toDictionaryArray | orderBy:'value'"></select>
回答by Dunc
As akonsu says, the feature has been requested here. However, I still couldn't get it to work with the latest (1.3.0) beta.
正如 akonsu 所说,已在此处请求该功能。但是,我仍然无法让它与最新的 (1.3.0) 测试版一起使用。
There's a nice workaroundburied in the comments (note this requires underscore, and you'll have to replace references to 'key' with 'value.$key' in the above example):
注释中有一个很好的解决方法(请注意,这需要下划线,并且您必须在上面的示例中用 'value.$key' 替换对 'key' 的引用):
[Add a filter]:
app.filter('toArray', function() { return function(obj) { if (!(obj instanceof Object)) return obj; return _.map(obj, function(val, key) { return Object.defineProperty(val, '$key', {__proto__: null, value: key}); }); }});Example markup:
<div ng-repeat="val in object | toArray | orderBy:'priority' | filter:fieldSearch"> {{val.$key}} : {{val}} </div>Potential downsides:
- Object.defineProperty will not work like this in IE8 (if you don't mind making $key enumerable then this is an easy change).
- If your property values are not objects then you can't set the $key property and this fails.
- It is not directly integrated into orderBy or ngRepeat so the syntax is different.
[添加过滤器]:
app.filter('toArray', function() { return function(obj) { if (!(obj instanceof Object)) return obj; return _.map(obj, function(val, key) { return Object.defineProperty(val, '$key', {__proto__: null, value: key}); }); }});示例标记:
<div ng-repeat="val in object | toArray | orderBy:'priority' | filter:fieldSearch"> {{val.$key}} : {{val}} </div>潜在的缺点:
- Object.defineProperty 在 IE8 中不会像这样工作(如果您不介意将 $key 设为可枚举,那么这是一个简单的更改)。
- 如果您的属性值不是对象,则您无法设置 $key 属性,这将失败。
- 它没有直接集成到 orderBy 或 ngRepeat 中,因此语法不同。
回答by joseym
Here's a good work around (angular-toArrayFilter):
这是一个很好的解决方法(angular-toArrayFilter):
.filter('toArray', function () {
return function (obj, addKey) {
if ( addKey === false ) {
return Object.keys(obj).map(function(key) {
return obj[key];
});
} else {
return Object.keys(obj).map(function (key) {
if(typeof obj[key] == 'object') return Object.defineProperty(obj[key], '$key', { enumerable: false, value: key});
});
}
};
});
回答by Patrick Tan
Instead of using orderby filter which only supports arrays and not objects. You can write your own filter like this I took the code from Justin Klemm http://justinklemm.com/angularjs-filter-ordering-objects-ngrepeat/and added support for specifying multiple ordering fields. The filter example below is to filter based on properties in the values but you can easily change it to filter based on the key as well.
而不是使用仅支持数组而不支持对象的 orderby 过滤器。您可以像这样编写自己的过滤器,我从 Justin Klemm http://justinklemm.com/angularjs-filter-ordering-objects-ngrepeat/ 获取了代码,并添加了对指定多个排序字段的支持。下面的过滤器示例是基于值中的属性进行过滤,但您也可以轻松地将其更改为基于键进行过滤。
app.filter('orderObjectBy', function()
{
return function(items, fields, reverse)
{
var filtered = [];
angular.forEach(items, function(item)
{
filtered.push(item);
});
filtered.sort(function (a, b)
{
var result = 0;
for (var i = 0; i < fields.length; ++i)
{
if (a[fields[i]] > b[fields[i]])
{
result = 1;
break;
}
else if (a[fields[i]] < b[fields[i]])
{
result = -1;
break;
}
}
return result;
});
if (reverse)
{
filtered.reverse();
}
return filtered;
};
});
Then inside your html5 web page use it like so where statistics is a map/dictionary with key value pairs.
然后在您的 html5 网页中使用它,就像这样,统计信息是带有键值对的地图/字典。
<div class="row" ng-repeat="stat in statistics | orderObjectBy: 'NumTimesPartnered', 'NumTimesOpponent']:true">
<div class="col col-33">{{stat.Name}}</div>
<div class="col"><center>{{stat.NumTimesPartnered}}</center></div>
<div class="col"><center>{{stat.NumTimesOpponent}}</center></div>
</div>

