Skip to content

refactor(multiple): use renderer for manual event bindings #30179

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

Merged
merged 1 commit into from
Dec 13, 2024

Conversation

crisbeto
Copy link
Member

Switches our manual calls into addEventListener to use the renderer instead so that tooling (e.g. the tracing service) gets notified about them.

Note that these changes only include the events that don't pass event options. The remaining events will be changed in a follow-up, because they require us to update to the latest next version of Angular.

@crisbeto crisbeto added the target: patch This PR is targeted for the next patch release label Dec 13, 2024
@crisbeto crisbeto force-pushed the events-renderer branch 2 times, most recently from 238bfd0 to d004e3a Compare December 13, 2024 10:28
this._hostElement.addEventListener('pointermove', this._onPointerMove.bind(this));
this._hostElement.addEventListener('pointerup', this._onPointerUp.bind(this));
this._listenerCleanups = [
renderer.listen(this._hostElement, 'pointerdown', this._onPointerDown.bind(this)),
Copy link
Member Author

Choose a reason for hiding this comment

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

Note that this one actually fixes a memory leak. Previously the events wouldn't have been removed, because bind returns a new function instead and for the removeEventListener call to work below, it has to be the same function.

@@ -28,6 +28,7 @@ export class DragDrop {
private _ngZone = inject(NgZone);
private _viewportRuler = inject(ViewportRuler);
private _dragDropRegistry = inject(DragDropRegistry);
private _renderer = inject(RendererFactory2).createRenderer(null, null);
Copy link
Member Author

Choose a reason for hiding this comment

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

Note that the renderer can't be injected in services so we have to go through the factory. Even though the method is called createRenderer, the service will return the same renderer every time: https://github.com/angular/angular/blob/main/packages/platform-browser/src/dom/dom_renderer.ts#L117

Copy link
Contributor

Choose a reason for hiding this comment

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

This seems a little unfortunate since it relies on the implementation in the framework. Would be nice (and out of scope) if Angular had some better supported API for the case of a servicing wanting the default renderer. As it reads, passing null, null is confusing and doesnt even seem like it should be valid

@crisbeto crisbeto marked this pull request as ready for review December 13, 2024 12:11
@crisbeto crisbeto requested a review from a team as a code owner December 13, 2024 12:11
@crisbeto crisbeto requested review from mmalerba and andrewseguin and removed request for a team December 13, 2024 12:11
Copy link
Contributor

@andrewseguin andrewseguin left a comment

Choose a reason for hiding this comment

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

@@ -28,6 +28,7 @@ export class DragDrop {
private _ngZone = inject(NgZone);
private _viewportRuler = inject(ViewportRuler);
private _dragDropRegistry = inject(DragDropRegistry);
private _renderer = inject(RendererFactory2).createRenderer(null, null);
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems a little unfortunate since it relies on the implementation in the framework. Would be nice (and out of scope) if Angular had some better supported API for the case of a servicing wanting the default renderer. As it reads, passing null, null is confusing and doesnt even seem like it should be valid

@@ -565,9 +577,10 @@ export class OverlayRef implements PortalOutlet {

/** Removes a backdrop element from the DOM. */
private _disposeBackdrop(backdrop: HTMLElement | null) {
this._cleanupBackdropClick?.();
this._cleanupBackdropClick?.();
Copy link
Contributor

Choose a reason for hiding this comment

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

should be _cleanupBackdropTransitionEnd?

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah good catch.

Switches our manual calls into `addEventListener` to use the renderer instead so that tooling (e.g. the tracing service) gets notified about them.

Note that these changes only include the events that don't pass event options. The remaining events will be changed in a follow-up, because they require us to update to the latest `next` version of Angular.
@crisbeto crisbeto removed the request for review from mmalerba December 13, 2024 19:38
@crisbeto crisbeto added the action: merge The PR is ready for merge by the caretaker label Dec 13, 2024
@crisbeto crisbeto merged commit 04e5e0f into angular:main Dec 13, 2024
20 of 22 checks passed
crisbeto added a commit that referenced this pull request Dec 13, 2024
Switches our manual calls into `addEventListener` to use the renderer instead so that tooling (e.g. the tracing service) gets notified about them.

Note that these changes only include the events that don't pass event options. The remaining events will be changed in a follow-up, because they require us to update to the latest `next` version of Angular.

(cherry picked from commit 04e5e0f)
crisbeto added a commit to crisbeto/angular that referenced this pull request Dec 20, 2024
In angular/components#30179 the CDK overlay started depending on the `Renderer2Factory`. Since the overlay is used in the `MatSnackbar` which is commonly used in error handlers, `Overlay` can end up being injected as a part of the app initialization. Because `AsyncAnimationRendererFactory` depends on the `ChangeDetectionScheduler`, it may cause a circular dependency.

These changes inject the `ChangeDetectionScheduler` lazily to avoid the error.

Note: this will also be resolved by angular#58984, but I decided to send it out, because:
1. angular#58984 seems to be stuck on some internal cleanup.
2. The `AsyncAnimationRendererFactory` doesn't need the `scheduler` eagerly anyway so the change is fairly safe.

Fixes angular#59255.
josephperrott pushed a commit to angular/angular that referenced this pull request Dec 20, 2024
)

In angular/components#30179 the CDK overlay started depending on the `Renderer2Factory`. Since the overlay is used in the `MatSnackbar` which is commonly used in error handlers, `Overlay` can end up being injected as a part of the app initialization. Because `AsyncAnimationRendererFactory` depends on the `ChangeDetectionScheduler`, it may cause a circular dependency.

These changes inject the `ChangeDetectionScheduler` lazily to avoid the error.

Note: this will also be resolved by #58984, but I decided to send it out, because:
1. #58984 seems to be stuck on some internal cleanup.
2. The `AsyncAnimationRendererFactory` doesn't need the `scheduler` eagerly anyway so the change is fairly safe.

Fixes #59255.

PR Close #59256
josephperrott pushed a commit to josephperrott/angular that referenced this pull request Dec 20, 2024
In angular/components#30179 the CDK overlay started depending on the `Renderer2Factory`. Since the overlay is used in the `MatSnackbar` which is commonly used in error handlers, `Overlay` can end up being injected as a part of the app initialization. Because `AsyncAnimationRendererFactory` depends on the `ChangeDetectionScheduler`, it may cause a circular dependency.

These changes inject the `ChangeDetectionScheduler` lazily to avoid the error.

Note: this will also be resolved by angular#58984, but I decided to send it out, because:
1. angular#58984 seems to be stuck on some internal cleanup.
2. The `AsyncAnimationRendererFactory` doesn't need the `scheduler` eagerly anyway so the change is fairly safe.

Fixes angular#59255.
josephperrott pushed a commit to angular/angular that referenced this pull request Dec 21, 2024
)

In angular/components#30179 the CDK overlay started depending on the `Renderer2Factory`. Since the overlay is used in the `MatSnackbar` which is commonly used in error handlers, `Overlay` can end up being injected as a part of the app initialization. Because `AsyncAnimationRendererFactory` depends on the `ChangeDetectionScheduler`, it may cause a circular dependency.

These changes inject the `ChangeDetectionScheduler` lazily to avoid the error.

Note: this will also be resolved by #58984, but I decided to send it out, because:
1. #58984 seems to be stuck on some internal cleanup.
2. The `AsyncAnimationRendererFactory` doesn't need the `scheduler` eagerly anyway so the change is fairly safe.

Fixes #59255.

PR Close #59271
@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 Jan 13, 2025
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 target: patch This PR is targeted for the next patch release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants