-
Notifications
You must be signed in to change notification settings - Fork 27.5k
ng-repeat throws a 'isecdom' error when iterating over an array with a "on" property #4805
Comments
I'm running into a similar issue when trying to use Backbone Collection methods in my templates because they also have Is there a way to make checking for DOM nodes more precise? |
we'll take a look at this next week. we are using heuristics to determine if objects are DOM nodes because there isn't a good standard way of doing this (one that works across browsers and iframes). if you have suggestions please let us know. the current check is here: Lines 45 to 65 in 3b1a4fe
|
I wrote some tests which might be a bit more reasonable, but also a fair bit more expensive: http://plnkr.co/edit/34DkkeB53HqpvR5SF7Le?p=preview Something that might be doable: if (obj && typeof obj === 'object') {
if (obj instanceof JQLite ||
obj instanceof Node ||
(jQuery && obj instanceof jQuery) {
return true;
}
/**
* Otherwise, test for some more peculiar jQuery functions which are
* present in all of the various cloned APIs or node properties... It isn't
* totally necessary to test their type (and this may have perf implications),
* but it's probably a better way to get an idea that they are an actual node.
* Keep in mind that the above code should cover most cases where each
* of these tests would be run --- in a falsy cases, this ends up being just
* two tests, plus the initial 3 or 4, plus the outter two.
*/
return (typeof obj.prop === 'function' && typeof obj.attr === 'function' &&
typeof obj.bind === 'function') ||
(typeof obj.nodeName === 'string' && typeof obj.nodeType === 'number');
}
return false; The instanceof shorthand might not be necessary and could hurt performance for false checks, which in $parse is probably the majority of the time. But it's still the most accurate way to do this, I believe, and much better than looking at specific properties. It would be good to write some benchmarks just to see how bad these are, or if it would make more sense to just look at using more node-specific function names. |
I've run some perf tests, using Anyways, instanceof Node ends up crawling up the prototype chain and that kind of sucks, so it's not very helpful perf-wise.... I guess the thing to do is replace obj.children && (obj.nodeName || (obj.on && obj.find))) with obj.children && (obj.nodeName || (obj.prop && obj.attr && obj.bind))) (maybe .bind isn't needed, but it seems good to test more rather than fewer, and it shouldn't hurt significantly) I guess I'll write this change and add some tests to make sure it doesn't break commonly used things, but keep in mind it is still possible to get false positives here. |
There are always going to be false positives here, unfortunately. But testing different properties will hopefully reduce the number of false positives in a meaningful way, without harming performance too much. Closes angular#4805
There are always going to be false positives here, unfortunately. But testing different properties will hopefully reduce the number of false positives in a meaningful way, without harming performance too much. Closes angular#4805
:( I have a "tree" object that has both |
FTW, from 1.6 onwards (with the sandbox removed), there will be no issue. |
Using AngularJS 1.2.0-rc3, the following throws the error "'Referencing DOM nodes in Angular expressions is disallowed!" in ensureSafeObject(). It seems to misinterpret the array as a DOM node because it has both a "find" and an "on" property.
Controller code:
Template:
The text was updated successfully, but these errors were encountered: