我想在迭代对象属性时使用带有ng-repeat指令的 orderBy 过滤器。 由于orderBy过滤器仅适用于Array,Angular doc建议使用 toArray 过滤器。
toArray过滤器的工作方式类似于具有以下对象属性的魅力:
var obj = {
a: { name: 'A' },
b: { name: 'B' },
c: { name: 'C' }
};
但是当与非对象属性一起使用时,它会导致无限摘要循环:
var obj = {
a: 'A',
b: 'B',
c: 'C'
};
这是一个说明问题的plunker。
答案 0 :(得分:1)
你不应该这样做,过滤器在转换数据时通常是个坏主意,因为每次摘要周期循环时都会重新计算过滤器。你的plunker不起作用,所以很难说为什么,但看代码我会说它确实使用每个摘要循环制作完全新的数组,并且在对象的情况下它添加了$ key属性,这有助于停止摘要循环。它不能将此属性添加到字符串。但我对此并不十分肯定。
编辑: 当您将console.log添加到toArray时:
return Object.keys(obj).map(function (key) {
var value = obj[key];
console.log(key, value);
return angular.isObject(value) ?
Object.defineProperty(value, '$key', { enumerable: false, value: key}) :
{ $key: key, $value: value };
});
在日志中,您可以看到问题的答案:
VM596 angular-toArrayFilter.js:15 b b
VM596 angular-toArrayFilter.js:15 a a
VM596 angular-toArrayFilter.js:15 c Object {p: "c"}
VM596 angular-toArrayFilter.js:15 b Object {p: "b"}
VM596 angular-toArrayFilter.js:15 a Object {p: "a"}
VM596 angular-toArrayFilter.js:15 c Object {p: "c", $key: "c"}
VM596 angular-toArrayFilter.js:15 b Object {p: "b", $key: "b"}
VM596 angular-toArrayFilter.js:15 a Object {p: "a", $key: "a"}
VM596 angular-toArrayFilter.js:15 c c
VM596 angular-toArrayFilter.js:15 b b
VM596 angular-toArrayFilter.js:15 a a
VM596 angular-toArrayFilter.js:15 c Object {p: "c", $$hashKey: "object:11", $key: "c"}
VM596 angular-toArrayFilter.js:15 b Object {p: "b", $$hashKey: "object:10", $key: "b"}
VM596 angular-toArrayFilter.js:15 a Object {p: "a", $$hashKey: "object:9", $key: "a"}
如果是对象,则角度使用相同的对象而不创建新对象。这样它就可以假设数组没有改变并结束了摘要周期。在字符串值的情况下,它在每次运行过滤器时都会创建新对象,因此它假定每次创建不同的数组时,它都不能结束摘要循环。