我有一个像这样的代码,在数据中使用ng-repeat =“(键,值)”。 在控制器中:
$scope.Dates = {"Today":"30",
"This Week":"42",
"This Month": "Oct",
"This Quarter" : "Bad",
"This Year" : 2013
}
和ng-repeat指令为
<div ng-repeat="(key,value) in Dates">
{{key}} ==> {{value}}
</div>
输出按顺序排列为
This Month ==> Oct
This Quarter ==> Bad
This Week ==> 42
This Year ==> 2013
Today ==> 30
如何摆脱这种排序(奇怪),因为我想要在代码中使用密钥..我检查了谷歌组,但有一个小提琴使用两个数组,其中一个存储键值。 http://jsfiddle.net/Saulzar/puhML/3/b。不想采用这种方法。
答案 0 :(得分:65)
这是JavaScript而非Angular的限制。
4.3.3对象是Object类型的成员。 这是属性的无序集合,每个属性都包含一个基元 价值,对象或功能。存储在属性中的函数 对象称为方法。
来自ECMAScript Language Specification
枚举属性的顺序[...] 未指定。
Angular sorts object keys explicitly,以便提供至少某种持久行为。
解决方法是迭代提取的密钥:
<div ng-repeat="key in keys(Dates)">
{{key}} ==> {{Dates[key]}}
</div>
$scope.keys = function(obj){
return obj? Object.keys(obj) : [];
}
$scope.Dates = {
"Today":"30",
"This Week":"42",
"This Month": "Oct",
"This Quarter" : "Bad",
"This Year" : 2013
};
答案 1 :(得分:10)
编辑:I've filed a bug,随意+1
ECMAScript没有指定应该迭代哪些键的顺序,但是所有主流浏览器都将对象实现为链接哈希映射(保留顺序),并且许多js库依赖于此行为,所以我们已经习惯了它并且它已经习惯了几乎没有改变。
另一方面,Angular(完全意外)按字母顺序排序。我自己检查了源代码,它在那里是硬编码的,如果它有一天得到解决将会很好。否则,(k, v) in obj
功能完全无用。
你真的无法做任何事情,欺骗角度认为你的结果是一个数组对任何事情都没用,因为你需要数字键然后......
如果可以,您可以定义getter的长度:
Object.defineProperty(yourResultObjectOrPrototype, 'length', {
get: function(){
return Object.keys(this).length;
}
})
否则你需要某种过滤器,它将使用for(var k in obj)
迭代对象并将结果存储在数组中。
答案 2 :(得分:7)
实际上有一个答案: 它被称为orderBy而不是排序:
https://docs.angularjs.org/api/ng/filter/orderBy
{{ orderBy_expression | orderBy : expression : reverse}}
<tr ng-repeat="friend in friends | orderBy:'-age'">
<td>{{friend.name}}</td>
<td>{{friend.phone}}</td>
<td>{{friend.age}}</td>
</tr>
您的列表只需要是一个列表,您可能需要一个索引来了解设置顺序
$scope.Dates = [{index:1, "Today":"30"},
{index:2,"This Week":"42"},
{index:3,"This Month": "Oct"},
{index:4,"This Quarter" : "Bad"},
{index:5,"This Year" : 2013}]
然后
<tr ng-repeat="(key, value) in Dates | orderBy:'index'">
<td>{{key}}</td>
<td>{{value}}</td>
</tr>
答案 3 :(得分:6)
查看详情here:
以前,通过将键排序为字母顺序,使用ngRepeat迭代对象属性时的项目顺序保证一致。
现在,项目的顺序取决于浏览器,具体取决于使用
for key in obj
语法迭代对象返回的顺序。似乎浏览器通常遵循按照定义键的顺序提供密钥的策略......
答案 4 :(得分:2)
我能够按字母顺序对字符串对象进行排序,使用ng-repeat!
在我的控制器中:
$scope.build_config = {
build_path : "/x/eng/build",
arch : "x86",
variant : "debug",
run_method : "boot",
};
$scope.get_keys = function (obj) {
if (obj)
return Object.keys(obj);
};
在我的HTML中:
<tr ng-repeat="key in get_keys(build_config) | orderBy:'toString()'">
<td> {{key}} </td>
<td> {{selected.build_config[key]}} </td>
</tr>
答案 5 :(得分:1)
Object.keys不保留订单 - FYI https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
//具有随机键排序的对象数组
var an_obj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.keys(an_obj)); // console: ['2', '7', '100']
我将它转换为对象数组
$scope.Dates = [
{ id: "Today", value:"30" },
{ id: "This Week", value:"42" },
{ id: "This Month", value: "Oct" },
{ id: "This Quarter", value : "Bad" },
{ id: "This Year", value : 2013 }
];
<li ng-repeat="date in Dates">{{date.id}} -> {{date.value}}</li>
答案 6 :(得分:0)
嗯,正如Angular的ngRepeat文档
中所述https://docs.angularjs.org/api/ng/directive/ngRepeat#iterating-over-object-properties
当使用它来迭代对象的属性时,它将不起作用
内置过滤器orderBy和filter不适用于对象,和 如果与一个一起使用将抛出错误。
在这种情况下,我认为最好的解决方案是使用数组而不是对象及其属性。因此,只需将其转换为数组,迭代对象的属性并推送到新数组即可。毕竟,我认为这将是集合的自然选择,而不是具有许多属性的单个对象。