mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(menu): menu content data being cleared when lazy-loaded content is reused between nested triggers (#12476)
Fixes an issue where a nested menu with lazy-loaded that is reused between multiple triggers will clear its content once an alternate trigger is hovered. The issue comes from the fact that we wait for the exit animation to finish before we detach the content, which ends up detaching the content of the new trigger as well. Fixes #12467.
This commit is contained in:
committed by
Jeremy Elbourn
parent
ef57919bd9
commit
1e1751f61e
@@ -18,6 +18,7 @@ import {
|
||||
} from '@angular/core';
|
||||
import {TemplatePortal, DomPortalOutlet} from '@angular/cdk/portal';
|
||||
import {DOCUMENT} from '@angular/common';
|
||||
import {Subject} from 'rxjs';
|
||||
|
||||
/**
|
||||
* Menu content that will be rendered lazily once the menu is opened.
|
||||
@@ -29,6 +30,9 @@ export class MatMenuContent implements OnDestroy {
|
||||
private _portal: TemplatePortal<any>;
|
||||
private _outlet: DomPortalOutlet;
|
||||
|
||||
/** Emits when the menu content has been attached. */
|
||||
_attached = new Subject<void>();
|
||||
|
||||
constructor(
|
||||
private _template: TemplateRef<any>,
|
||||
private _componentFactoryResolver: ComponentFactoryResolver,
|
||||
@@ -60,6 +64,7 @@ export class MatMenuContent implements OnDestroy {
|
||||
// risk it staying attached to a pane that's no longer in the DOM.
|
||||
element.parentNode!.insertBefore(this._outlet.outletElement, element);
|
||||
this._portal.attach(this._outlet, context);
|
||||
this._attached.next();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -245,9 +245,14 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
|
||||
if (menu.lazyContent) {
|
||||
// Wait for the exit animation to finish before detaching the content.
|
||||
menu._animationDone
|
||||
.pipe(filter(event => event.toState === 'void'), take(1))
|
||||
.subscribe(() => {
|
||||
menu.lazyContent!.detach();
|
||||
.pipe(
|
||||
filter(event => event.toState === 'void'),
|
||||
take(1),
|
||||
// Interrupt if the content got re-attached.
|
||||
takeUntil(menu.lazyContent._attached)
|
||||
)
|
||||
.subscribe(() => menu.lazyContent!.detach(), undefined, () => {
|
||||
// No matter whether the content got re-attached, reset the menu.
|
||||
this._resetMenu();
|
||||
});
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user