You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix($compile): connect transclude scopes to their containing scope to prevent memory leaks
Transcluded scopes are now connected to the scope in which they are created via their `$parent`
property. This means that they will be automatically destroyed when their "containing" scope is
destroyed, without having to resort to listening for a `$destroy` event on various DOM elements
or other scopes.
Previously, transclude scope not only inherited prototypically from the scope from which they were
transcluded but they were also still owned by that "outer" scope. This meant that there were
scenarios where the "real" container scope/element was destroyed but the transclude scope was not,
leading to memory leaks.
The original strategy for dealing with this was to attach a `$destroy` event handler to the DOM
elements in the transcluded content, so that if the elements were removed from the DOM then their
associated transcluded scope would be destroyed.
This didn't work for transclude contents that didn't contain any elements - most importantly in
the case of the transclude content containing an element transclude directive at its root, since
the compiler swaps out this element for a comment before a destroy handler could be attached.
BREAKING CHANGE:
`$transclude` functions no longer attach `$destroy` event handlers to the transcluded content,
and so the associated transclude scope will not automatically be destroyed if you remove a
transcluded element from the DOM using direct DOM manipulation such as the jquery `remove()`
method.
If you want to explicitly remove DOM elements inside your directive that have been compiled, and so
potentially contain child (and transcluded) scopes, then it is your responsibility to get hold of
the scope and destroy it at the same time.
The suggested approach is to create a new child scope of your own around any DOM elements that you
wish to manipulate in this way and destroy those scopes if you remove their contents - any child
scopes will then be destroyed and cleaned up automatically.
Note that all the built-in directives that manipulate the DOM (ngIf, ngRepeat, ngSwitch, etc)
already follow this best practice, so if you only use these for manipulating the DOM then you
do not have to worry about this change.
Closesangular#9095
0 commit comments