-
Notifications
You must be signed in to change notification settings - Fork 27.5k
Conversation
Ouch! Will take a look. Any thoughts on a fix? |
Can easily make jqLite the same as jQuery (a196c8b should have done that), I think that's a good start to at least fix the big leak and make jqLite/jQuery the same. Not sure about listening to the element $destroy when the element is currently a transclusion comment node... |
The plunk is "not found" |
Oops, I probably forgot to hit save, here's a new one: http://plnkr.co/edit/89BK3LXL6USYoATQhg2c?p=preview |
Does this section of code seem relevant: https://github.com/angular/angular.js/blob/master/src/ng/compile.js#L1561-L1566
Perhaps we need something a bit more generic for element transclusion directives - i.e. rather than specifically fixing it only for controllers, we should fix it for anything that might want to add data to the element when it is a comment? |
It seems that the problem is not actually to do with the directives being nested but instead that ng-if is both using "element" transclusion and is calling the translusion function asynchronously, after compilation has completed. Here is a failing test:
|
Actually my test there is just wrong ignore it. It is failing for other reasons ... |
looking into this... |
was this determined to be a regression? I'm not sure this ever worked correctly |
Iterate only over elements and not nodes since we don't attach data or handlers to text/comment nodes.
I am pretty sure it is a regression because of e35abc9 |
Or at least part of it is a regression |
@jbedard the second "modified" test was not actually valid. It was failing for a different reason than you suggested and so doesn't help us identify a leak when using jQuery. Here is the test, still using ngIf but fixed so it is no longer a false-negative.
|
In fact I don't see the memory leak happening when jQuery is loaded. See |
Reverting e35abc9 removes the memory leak from the jqLite version: |
OK, so the problem with jqLite is that if we have a directive that can span multiple elements, like ngIf and ngRepeat then you get an array back from the translude as the clone here: https://github.com/angular/angular.js/blob/master/src/ng/compile.js#L1005
We then try to attach the $destroy event handler, correctly to the first element, the ngIf, but also incorrectly to the ngIfEnd comment node. We should just change |
I think for ngIf and ngRepeat there is only a comment node, not an array of nodes, so I think the use of .on causing jQuery element removal to not work is an old issue, the jqLite memory leak is new now that jqLite is is trying to be more like jQuery and not supporting data/events on non-element/document nodes. |
The ngIfEnd comment node is another case that will reproduce the jqLite data leak. |
This is what jQuery does by default: https://github.com/jquery/jquery/blob/c18c6229c84cd2f0c9fe9f6fc3749e2c93608cc7/src/data/accepts.js#L16 We don't need to set data on text/comment nodes internally and if we don't allow setting data on these nodes, we don't need to worry about cleaning it up. BREAKING CHANGE: previously it was possible to set jqLite data on Text/Comment nodes, but now that is allowed only on Element and Document nodes just like in jQuery. We don't expect that app code actually depends on this accidental feature.
We were attaching handlers to comment nodes when setting up bound transclusion functions. But we don't clean up comments and text nodes when deallocating so there was a memory leak. Closes angular#7913
We were attaching handlers to comment nodes when setting up bound transclusion functions. But we don't clean up comments and text nodes when deallocating so there was a memory leak. Closes angular#7913
We were attaching handlers to comment nodes when setting up bound transclusion functions. But we don't clean up comments and text nodes when deallocating so there was a memory leak. Closes angular#7913 Closes angular#7942
When the transclude function creates the scope it destroys that scope on the '$destroy' jQuery event. If that element is a comment (because it was also transcluded, for example) then:
Here's another example: http://plnkr.co/edit/89BK3LXL6USYoATQhg2c?p=preview