-
Notifications
You must be signed in to change notification settings - Fork 6.8k
feat(menu): support lazy rendering and passing in context data #9271
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
Conversation
58fb254 to
5e636f9
Compare
src/lib/menu/menu-content.ts
Outdated
| const element: HTMLElement = this._template.elementRef.nativeElement; | ||
|
|
||
| // Since the menu might be attached to a different DOM node, we have to re-insert it every time. | ||
| element.parentNode!.insertBefore(this._outlet.hostDomElement, element); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't quite follow why this is necessary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's because we can have the menu be opened by different triggers which in turn have their own OverlayRef with a different pane. If we didn't do this, the element could end up in limbo if you opened it using two different triggers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add that explanation as a comment?
| import {DOCUMENT} from '@angular/common'; | ||
|
|
||
| /** | ||
| * Menu content that will be rendered lazily once the menu is opened. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would an end user need to ever interact with this class (i.e. should it be docs-private)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did it, because we support providing your own menu instance that matches the MatMenuPanel interface.
| with the `matMenuContent` attribute: | ||
|
|
||
| ```html | ||
| <mat-menu #appMenu="matMenu"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think of avoiding the extra matMenuContent by letting people add matMenu to an ng-template element? Something like
<ng-template matMenu>
...
</ng-template>The selector for the menu would change to mat-menu, ng-template[matMenu]. The menu would then optionally inject TemplateRef and go through the extra steps if one is present.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's what I was going for initially, but Angular throws an error when you have a component on an ng-template. The alternative would be to use a directive, but we can't do that either, because we need to wrap the menu content in a div to add the proper styling and for the animation to work.
jelbourn
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, just minor comments. Add merge-ready when ready
src/lib/menu/menu-content.ts
Outdated
| const element: HTMLElement = this._template.elementRef.nativeElement; | ||
|
|
||
| // Since the menu might be attached to a different DOM node, we have to re-insert it every time. | ||
| element.parentNode!.insertBefore(this._outlet.hostDomElement, element); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add that explanation as a comment?
src/cdk/portal/dom-portal-outlet.ts
Outdated
| constructor( | ||
| private _hostDomElement: Element, | ||
| /** Element into which the content is projected. */ | ||
| public hostDomElement: Element, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe rename this to outletElement? I think the "host" is leftover from the old class name
5e636f9 to
607d9c8
Compare
607d9c8 to
0a759e0
Compare
|
@crisbeto passes Google presubmit, just needs rebase |
0a759e0 to
6febb78
Compare
|
Rebased. |
|
@crisbeto failing on Travis now |
6febb78 to
7f87d91
Compare
* Introduces the `matMenuContent` directive that allows for menu content to be rendered lazily. * Adds the `matMenuTriggerData` input to the `MatMenuTrigger` that allows for contextual data to be passed in to the lazily-rendered menu panel. This allows for the menu instance to be re-used between triggers. Fixes angular#9251.
7f87d91 to
192be85
Compare
|
Fixed the test failure. |
|
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
matMenuContentdirective that allows for menu content to be rendered lazily.matMenuTriggerDatainput to theMatMenuTriggerthat allows for contextual data to be passed in to the lazily-rendered menu panel. This allows for the menu instance to be re-used between triggers.Fixes #9251.