mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-05-14 09:43:12 +00:00
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.
This commit is contained in:
parent
000012f319
commit
fad626f304
2 changed files with 32 additions and 12 deletions
|
|
@ -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, ...)
|
* @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments, ...)
|
||||||
*/
|
*/
|
||||||
function isArrayLike(obj) {
|
function isArrayLike(obj) {
|
||||||
if (!obj || (typeof obj.length !== 'number')) return false;
|
if (obj == null || isWindow(obj)) {
|
||||||
|
return false;
|
||||||
// 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;
|
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var length = obj.length;
|
||||||
|
|
||||||
|
if (obj.nodeType === 1 && length) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isArray(obj) || !isFunction(obj) && (
|
||||||
|
length === 0 || typeof length === "number" && length > 0 && (length - 1) in obj
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,27 @@ describe('ngRepeat', function() {
|
||||||
expect(element.find('li').length).toEqual(3);
|
expect(element.find('li').length).toEqual(3);
|
||||||
expect(element.text()).toEqual('x;y;x;');
|
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(
|
||||||
|
'<ul>' +
|
||||||
|
'<li ng-repeat="item in items">{{item.name}};</li>' +
|
||||||
|
'</ul>')(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() {
|
it('should iterate over on object/map', function() {
|
||||||
element = $compile(
|
element = $compile(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue