Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(forms): more precise control cleanup #39623

Closed

Conversation

AndrewKushnir
Copy link
Contributor

Currently when an instance of the FormControlName directive is destroyed, the Forms package invokes
the cleanUpControl to clear all directive-specific logic (such as validators, onChange handlers,
etc) from a bound control. The logic of the cleanUpControl function should revert all setup
performed by the setUpControl function. However the cleanUpControl is too aggressive and removes
all callbacks related to the onChange and disabled state handling. This is causing problems when
a form control is bound to multiple FormControlName` directives, causing other instances of that
directive to stop working correctly when the first one is destroyed.

This commit updates the cleanup logic to only remove callbacks added while setting up a control
for a given directive instance.

The fix is needed to allow adding cleanUpControl function to other places where cleanup is needed
(missing this function calls in some other places causes memory leak issues).

PR Type

What kind of change does this PR introduce?

  • Bugfix

Does this PR introduce a breaking change?

  • Yes
  • No

@AndrewKushnir AndrewKushnir added type: bug/fix action: review The PR is still awaiting reviews from at least one requested reviewer area: forms target: patch This PR is targeted for the next patch release labels Nov 10, 2020
@ngbot ngbot bot added this to the needsTriage milestone Nov 10, 2020
@google-cla google-cla bot added the cla: yes label Nov 10, 2020
@AndrewKushnir AndrewKushnir force-pushed the forms-cleanup-control branch 2 times, most recently from 2d1be6a to bd54312 Compare November 10, 2020 07:30
@AndrewKushnir
Copy link
Contributor Author

Presubmit.

Copy link
Member

@petebacondarwin petebacondarwin left a comment

Choose a reason for hiding this comment

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

Lgtm - a few nits. I assume that the changes to the circular deps are just due to reordering of the imports rather than any substantial differences?

packages/forms/test/reactive_integration_spec.ts Outdated Show resolved Hide resolved
packages/forms/test/reactive_integration_spec.ts Outdated Show resolved Hide resolved
packages/forms/src/directives/ng_form.ts Outdated Show resolved Hide resolved
Currently when an instance of the `FormControlName` directive is destroyed, the Forms package invokes
the `cleanUpControl` to clear all directive-specific logic (such as validators, onChange handlers,
etc) from a bound control. The logic of the `cleanUpControl` function should revert all setup
performed by the `setUpControl` function. However the `cleanUpControl` is too aggressive and removes
all callbacks related to the onChange and disabled state handling. This is causing problems when
a form control is bound to multiple FormControlName` directives, causing other instances of that
directive to stop working correctly when the first one is destroyed.

This commit updates the cleanup logic to only remove callbacks added while setting up a control
for a given directive instance.

The fix is needed to allow adding `cleanUpControl` function to other places where cleanup is needed
(missing this function calls in some other places causes memory leak issues).
@AndrewKushnir AndrewKushnir marked this pull request as ready for review November 11, 2020 02:15
@AndrewKushnir AndrewKushnir added action: presubmit The PR is in need of a google3 presubmit and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels Nov 11, 2020
@AndrewKushnir
Copy link
Contributor Author

AndrewKushnir commented Nov 11, 2020

Thanks for review @petebacondarwin, great feedback! I've applied the necessary changes, please have a look when you get a sec.

I assume that the changes to the circular deps are just due to reordering of the imports rather than any substantial differences?

Yeah, there are no substantial differences. I can do some cleanup by moving things around once this change (and the followup PR) lands.

(Note to self: I've also started a new presubmit + global presubmit)

Copy link
Member

@petebacondarwin petebacondarwin left a comment

Choose a reason for hiding this comment

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

LGTM - nice work @AndrewKushnir!

@AndrewKushnir
Copy link
Contributor Author

Thanks for the review @petebacondarwin 👍

Global presubmit went well (no regressions), so I'm adding this PR to the merge queue.

Thank you.

@AndrewKushnir AndrewKushnir added action: merge The PR is ready for merge by the caretaker and removed action: presubmit The PR is in need of a google3 presubmit labels Nov 11, 2020
@atscott atscott closed this in 1bc53eb Nov 12, 2020
atscott pushed a commit that referenced this pull request Nov 12, 2020
Currently when an instance of the `FormControlName` directive is destroyed, the Forms package invokes
the `cleanUpControl` to clear all directive-specific logic (such as validators, onChange handlers,
etc) from a bound control. The logic of the `cleanUpControl` function should revert all setup
performed by the `setUpControl` function. However the `cleanUpControl` is too aggressive and removes
all callbacks related to the onChange and disabled state handling. This is causing problems when
a form control is bound to multiple FormControlName` directives, causing other instances of that
directive to stop working correctly when the first one is destroyed.

This commit updates the cleanup logic to only remove callbacks added while setting up a control
for a given directive instance.

The fix is needed to allow adding `cleanUpControl` function to other places where cleanup is needed
(missing this function calls in some other places causes memory leak issues).

PR Close #39623
@maxime1992
Copy link

@AndrewKushnir is this fixing #20007 by any chance 🙏 ?

@AndrewKushnir
Copy link
Contributor Author

AndrewKushnir commented Nov 12, 2020

@maxime1992 thanks for the question. No, this PR would not help with memory management, but it's a prerequisite for #39235, which should address the memory leak issue caused by the FormControlName directive in some scenarios. I plan to rebase #39235 asap, add more tests (and actually test that there is no mem leak) and reply in #20007. Thank you.

@maxime1992
Copy link

That. is. awesome. Thank you so much for looking into this 🙏 🎉

@AndrewKushnir
Copy link
Contributor Author

@maxime1992 JFYI I came across another issue while testing #39235 with the formGroup directives and I've created a separate PR to resolve it, see #39235 (comment). Once PR #39685 lands, I should be able to continue testing #39235 with additional scenarios.

basherr pushed a commit to basherr/angular that referenced this pull request Nov 14, 2020
Currently when an instance of the `FormControlName` directive is destroyed, the Forms package invokes
the `cleanUpControl` to clear all directive-specific logic (such as validators, onChange handlers,
etc) from a bound control. The logic of the `cleanUpControl` function should revert all setup
performed by the `setUpControl` function. However the `cleanUpControl` is too aggressive and removes
all callbacks related to the onChange and disabled state handling. This is causing problems when
a form control is bound to multiple FormControlName` directives, causing other instances of that
directive to stop working correctly when the first one is destroyed.

This commit updates the cleanup logic to only remove callbacks added while setting up a control
for a given directive instance.

The fix is needed to allow adding `cleanUpControl` function to other places where cleanup is needed
(missing this function calls in some other places causes memory leak issues).

PR Close angular#39623
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Dec 15, 2020
@pullapprove pullapprove bot added area: build & ci Related the build and CI infrastructure of the project area: core Issues related to the framework runtime labels Dec 15, 2020
@ngbot ngbot bot modified the milestones: needsTriage, Backlog Dec 15, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker area: build & ci Related the build and CI infrastructure of the project area: core Issues related to the framework runtime area: forms cla: yes target: patch This PR is targeted for the next patch release type: bug/fix
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants