mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-17 07:40:22 +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, ...)
|
||||
*/
|
||||
function isArrayLike(obj) {
|
||||
if (!obj || (typeof obj.length !== 'number')) 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)
|
||||
if (obj == null || isWindow(obj)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
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.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() {
|
||||
element = $compile(
|
||||
|
|
|
|||
Loading…
Reference in a new issue