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(angular): inline overlay dynamic template data #24521

Merged
merged 1 commit into from
Jan 6, 2022
Merged

Conversation

sean-perkins
Copy link
Contributor

@sean-perkins sean-perkins commented Jan 6, 2022

Pull request checklist

Please check if your PR fulfills the following requirements:

  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been reviewed and added / updated if needed (for bug fixes / features)
  • Build (npm run build) was run locally and any changes were pushed
  • Lint (npm run lint) has passed locally and any fixes were made for failures

Pull request type

Please check the type of change your PR introduces:

  • Bugfix
  • Feature
  • Code style update (formatting, renaming)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • Documentation content changes
  • Other (please describe):

What is the current behavior?

Angular inline modals and popovers do not update their template contents when change detection occurs. This results in structural directives (*ngIf, *ngFor), pipes and bindings to not update after the component is initialized.

Issue Number: Resolves #24502

What is the new behavior?

Inline modals and popovers will correctly re-render their template contents when change detection occurs.

Does this introduce a breaking change?

  • Yes
  • No

Other information

Before After
Kapture.2022-01-05.at.22.44.57.mp4
Kapture.2022-01-05.at.22.41.40.mp4

@sean-perkins sean-perkins requested a review from a team as a code owner January 6, 2022 03:46
@github-actions github-actions bot added the package: angular @ionic/angular package label Jan 6, 2022
@@ -103,7 +103,6 @@ export class IonModal {
protected el: HTMLElement;

constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this need to be done for inline popovers as well? https://github.com/ionic-team/ionic-framework/blob/main/angular/src/directives/overlays/popover.ts#L107

Additionally, how does this impact change detection with a controller (if it impacts it at all)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch, this did affect popovers as well. I've updated the PR to resolve and test both. I've also reworked the commit since this is more about inline overlays and less specific to just modals.

Tested with controllers & attached change detection and things are working as expected. I cannot notice an impact.

Copy link
Contributor

Choose a reason for hiding this comment

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

I was wondering why this call was added in the first place, and traced it back to the inline modal feature PR: https://github.com/ionic-team/ionic-framework/pull/23341/files#diff-d123478d8d877b48ad22b0a74610bcd649b94548e5e5c56a173bb3506d506e88R25 @liamdebeasi Can you think of why this was added originally? I'm wondering if there was some edge case bug this was meant to fix 🤔

Copy link
Contributor

Choose a reason for hiding this comment

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

c.detach() is what all the other components do, which is why I added it https://github.com/ionic-team/ionic-framework/blob/main/angular/src/directives/proxies.ts#L26

Copy link
Contributor

Choose a reason for hiding this comment

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

Huh... do we have our own change detection set up or something? 🤨

Copy link
Contributor Author

Choose a reason for hiding this comment

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

How we "wrap" our web components into Angular is sorta special. We basically target the same selector tag as our web component, but then use Angular's content projection with ng-content to slot the existing web component inside the wrapping Angular component; since ng-content isn't an actual DOM node this results in ion-modal equalling our web component node.

We then typically detach from all of Angular's change detection, because the updating of the web component should be driven through our implementation in Stencil and independent to anything in Angular. We don't want to cause an unwanted repaint of the web component. We only pass through inputs from our proxy to the web component node, so that the web component can decide when a re-render is necessary.

Overlays are a special condition (inline most specifically), because we are reliant on using ng-template since we are using template outlets (Angular feature). In Ivy, they fixed ng-template to have its own change detection reference to render changes inside just that template context. When we "detach" we are opting out of that behavior. With controller implementations the custom Angular component the implementer creates; would drive the change detection of the template (which wouldn't be detached by default).

For all our other UI components, opting out makes sense. We aren't needing the benefits of functionality that Angular brings with what the web component needs.

Copy link
Contributor

Choose a reason for hiding this comment

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

So that's what those are for here! Thanks for the in-depth explanation 👍 If controller modals/popovers still work as expected (i.e. no extra repaints) then this sounds good to me.

Copy link
Contributor

Choose a reason for hiding this comment

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

It would be good to note this somewhere either in the Ionic wiki or in the comments in this code

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Adding a notion doc for now in our internal documents.

@sean-perkins sean-perkins changed the title fix(angular): inline modal dynamic template data fix(angular): inline overlay dynamic template data Jan 6, 2022
Copy link
Contributor

@liamdebeasi liamdebeasi left a comment

Choose a reason for hiding this comment

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

Nice job! Also make sure commit subject follows our guidelines too

Allow template bindings to update with inline overlays.

Resolves #24502
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
package: angular @ionic/angular package
Projects
None yet
Development

Successfully merging this pull request may close these issues.

bug: Angular Inline Sheet Modal are not updated
3 participants