问题
I have a table with rows created by ng-repeat. Table headers have an ng-click that sets the predicate for the sorting (the function also determines direction, asc/desc). The sorting works fine, but for some reason I get exceptions from jQuery every time I change the predicate and the sort fires.
Here is a plunkr example of what I am doing : http://plnkr.co/edit/qfNcm9RPQSsNgqmm3TYS?p=preview
As you can see in the plnkr, the ng-repeat is pretty simple. The ng-repeat in our project is similar and not any more complicated.
<tr ng-repeat="contest in AllContests | orderBy:sort:ReverseSort" ng-show="contest.isVisible">
This actually happens in a number of places in our code and we use different methods of sorting among them, but they are still affected.
The table headers can be clicked to sort the items. That plunkr does not exhibit the problem. Even though the sorting works on my page, it breaks other things on the page (like a slick carousel control). The exception is on line 1430 in jquery.js (ver 2.1.1 via Google CDN which includes Sizzle.js). The method in which the exception happens is Sizzle.attr. It looks like what is happening is it is looping through all of the elements created with the ng-repeat, and getting attribute values from them. The exception happens when it gets to the " end ngRepeat: contest in AllContests | orderBy:sort:ReverseSort " comment that signifies the end of the ng-repeat section.
Specifically I am getting 'Uncaught TypeError: undefined is not a function' when it tries to getAttribute() on the element.
return val !== undefined ?
val :
support.attributes || !documentIsHTML ?
elem.getAttribute( name ) :
(val = elem.getAttributeNode(name)) && val.specified ?
val.value :
null;
Now, I could pull jquery, add it to my project edit it so that it evaluates elem.nodeName == "#comment", and just return null in that case. I would much rather know if I am doing something incorrectly or if there is a better way of doing this.
Otherwise, is there a way of overriding that method and supplying my own without editing the jquery library?
EDIT
Here is an example of the problem in action: https://playmlf.com/Lobby/ContestLobby
Temporary Resolution
I have edited the jQuery library so that it looks thusly:
Sizzle.attr = function (elem, name) {
if (elem.nodeName == '#comment') return null;
// Set document vars if needed
if ( ( elem.ownerDocument || elem ) !== document ) {
setDocument( elem );
}
NOTE: this is only the top portion of the Sizzle.attr method. The first if
is the line of interest. It returns null if the element is a comment. I did not want to edit the jquery library, but I was unable to figure out how to override this particular method, or keep it from being called in the first place during a sort. I don't like this fix, but at the same time I have spent WAY too much time on this and need something that works. I will pay the bad fix tax later.
回答1:
This seems to occur because Comment element does not have getAttribute method.
There is a bug logged for this. As a workaround, you can add this to your codebase and make sure that it gets executed early on:
Object.getPrototypeOf(document.createComment('')).getAttribute = function() {}
来源:https://stackoverflow.com/questions/27408501/ng-repeat-sorting-is-throwing-an-exception-in-jquery