Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit fad626f

Browse files
dchermanksheedlo
authored andcommitted
fix(isArrayLike) Correctly detect arrayLike items
Change the implementation of isArrayLike to use one heavily based on the implementation in jQuery in order to correctly detect array-like objects, that way functionality like ngRepeat works as expected.
1 parent 000012f commit fad626f

File tree

2 files changed

+30
-10
lines changed

2 files changed

+30
-10
lines changed

src/Angular.js

+10-10
Original file line numberDiff line numberDiff line change
@@ -80,19 +80,19 @@ var /** holds major version number for IE or NaN for real browsers */
8080
* @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments, ...)
8181
*/
8282
function isArrayLike(obj) {
83-
if (!obj || (typeof obj.length !== 'number')) return false;
83+
if (obj == null || isWindow(obj)) {
84+
return false;
85+
}
86+
87+
var length = obj.length;
8488

85-
// We have on object which has length property. Should we treat it as array?
86-
if (typeof obj.hasOwnProperty != 'function' &&
87-
typeof obj.constructor != 'function') {
88-
// This is here for IE8: it is a bogus object treat it as array;
89+
if (obj.nodeType === 1 && length) {
8990
return true;
90-
} else {
91-
return obj instanceof JQLite || // JQLite
92-
(jQuery && obj instanceof jQuery) || // jQuery
93-
toString.call(obj) !== '[object Object]' || // some browser native object
94-
typeof obj.callee === 'function'; // arguments (on IE8 looks like regular obj)
9591
}
92+
93+
return isArray(obj) || !isFunction(obj) && (
94+
length === 0 || typeof length === "number" && length > 0 && (length - 1) in obj
95+
);
9696
}
9797

9898
/**

test/ng/directive/ngRepeatSpec.js

+20
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,27 @@ describe('ngRepeat', function() {
7777
expect(element.find('li').length).toEqual(3);
7878
expect(element.text()).toEqual('x;y;x;');
7979
});
80+
81+
it('should iterate over an array-like class', function() {
82+
function Collection() {}
83+
Collection.prototype = new Array();
84+
Collection.prototype.length = 0;
8085

86+
var collection = new Collection();
87+
collection.push({ name: "x" });
88+
collection.push({ name: "y" });
89+
collection.push({ name: "z" });
90+
91+
element = $compile(
92+
'<ul>' +
93+
'<li ng-repeat="item in items">{{item.name}};</li>' +
94+
'</ul>')(scope);
95+
96+
scope.items = collection;
97+
scope.$digest();
98+
expect(element.find('li').length).toEqual(3);
99+
expect(element.text()).toEqual('x;y;z;');
100+
});
81101

82102
it('should iterate over on object/map', function() {
83103
element = $compile(

0 commit comments

Comments
 (0)