Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

fix(ngRepeat): fix trackBy function being invoked with incorrect scope #16777

Merged
merged 2 commits into from Dec 6, 2018

Conversation

jbedard
Copy link
Contributor

@jbedard jbedard commented Nov 29, 2018

This also fixes a leak of that scope across all further instances of the
repeated element.

Fixes #16776

What is the current behavior? (You can also link to an open issue here)
The track-by function would get created on the first linking of an ng-repeat and then get cached forever, so each time that ng-repeat was re-linked (when it is repeated, or destroyed+recreated via ng-if etc.) the previous scope would be used. This also "leaks" the scope for the lifetime of that compiled node.

What is the new behavior (if this is a feature change)?
The track-by no longer directly references the scope

Copy link
Member

@gkalpak gkalpak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

test/ng/directive/ngRepeatSpec.js Outdated Show resolved Hide resolved
test/ng/directive/ngRepeatSpec.js Show resolved Hide resolved
test/ng/directive/ngRepeatSpec.js Outdated Show resolved Hide resolved
@gkalpak
Copy link
Member

gkalpak commented Nov 29, 2018

For future reference, this was broken in bdd853c.

jbedard added a commit to jbedard/angular.js that referenced this pull request Nov 29, 2018
This also fixes a leak of that scope across all further instances of the
repeated element.

Fixes angular#16776
Closes angular#16777
jbedard added a commit to jbedard/angular.js that referenced this pull request Nov 30, 2018
Also fixes a leak of that scope across all further instances of the
repeated element.

Fixes angular#16776
Closes angular#16777

// Clear the value property from the hashFnLocals object to prevent a reference to the last value
// being leaked into this ngRepeatCompile function scope
hashFnLocals[valueIdentifier] = undefined;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WDYT about clearing the value here? This way we don't have to touch the trackByIdExpFn method that gets invoked on each element and just add this one assignment at the end.

src/ng/directive/ngRepeat.js Outdated Show resolved Hide resolved
// Clear the value property from the hashFnLocals object to prevent a reference to the last value
// being leaked into this ngRepeatCompile function scope
if (hashFnLocals) {
hashFnLocals[valueIdentifier] = undefined;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about keyIdentifier? Can't is be non-primitive?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The keyIdentifier value is either an index or the itemKey from for (var itemKey in collection). So it should always be a number or string.

@jbedard
Copy link
Contributor Author

jbedard commented Dec 1, 2018

The build is all green 😲

@jbedard
Copy link
Contributor Author

jbedard commented Dec 6, 2018

I rebased just to add "Ref #16776" to the second commit message, and got the build green again!

@jbedard jbedard merged commit de0aad8 into angular:master Dec 6, 2018
jbedard added a commit that referenced this pull request Dec 6, 2018
Also fixes a leak of that scope across all further instances of the
repeated element.

Fixes #16776
Closes #16777
mgol pushed a commit that referenced this pull request Dec 6, 2018
Also fixes a leak of that scope across all further instances of the
repeated element.

Fixes #16776
Closes #16777
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ngRepeat "track by" possible memory leak
4 participants