diff --git a/src/Angular.js b/src/Angular.js index 4e050a0ce07f..88afe45c0ef5 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -80,19 +80,19 @@ var /** holds major version number for IE or NaN for real browsers */ * @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments, ...) */ function isArrayLike(obj) { - if (!obj || (typeof obj.length !== 'number')) return false; + if (obj == null || isWindow(obj)) { + return false; + } + + var length = obj.length; - // We have on object which has length property. Should we treat it as array? - if (typeof obj.hasOwnProperty != 'function' && - typeof obj.constructor != 'function') { - // This is here for IE8: it is a bogus object treat it as array; + if (obj.nodeType === 1 && length) { return true; - } else { - return obj instanceof JQLite || // JQLite - (jQuery && obj instanceof jQuery) || // jQuery - toString.call(obj) !== '[object Object]' || // some browser native object - typeof obj.callee === 'function'; // arguments (on IE8 looks like regular obj) } + + return isArray(obj) || !isFunction(obj) && ( + length === 0 || typeof length === "number" && length > 0 && (length - 1) in obj + ); } /** diff --git a/test/ng/directive/ngRepeatSpec.js b/test/ng/directive/ngRepeatSpec.js index 26562f4e660a..97e726e2e2af 100644 --- a/test/ng/directive/ngRepeatSpec.js +++ b/test/ng/directive/ngRepeatSpec.js @@ -77,7 +77,27 @@ describe('ngRepeat', function() { expect(element.find('li').length).toEqual(3); expect(element.text()).toEqual('x;y;x;'); }); + + it('should iterate over an array-like class', function() { + function Collection() {} + Collection.prototype = new Array(); + Collection.prototype.length = 0; + var collection = new Collection(); + collection.push({ name: "x" }); + collection.push({ name: "y" }); + collection.push({ name: "z" }); + + element = $compile( + '')(scope); + + scope.items = collection; + scope.$digest(); + expect(element.find('li').length).toEqual(3); + expect(element.text()).toEqual('x;y;z;'); + }); it('should iterate over on object/map', function() { element = $compile(