fix(menu): wait until all menus are ready

fixes #15727
This commit is contained in:
Manu Mtz.-Almeida
2018-10-01 17:31:55 +02:00
parent e916500e69
commit a5c2cc1835
3 changed files with 21 additions and 8 deletions

View File

@ -16,6 +16,7 @@ export class MenuController implements MenuControllerI {
private menuAnimations = new Map<string, AnimationBuilder>(); private menuAnimations = new Map<string, AnimationBuilder>();
@Prop({ connect: 'ion-animation-controller' }) animationCtrl!: HTMLIonAnimationControllerElement; @Prop({ connect: 'ion-animation-controller' }) animationCtrl!: HTMLIonAnimationControllerElement;
@Prop({ context: 'document' }) doc!: Document;
constructor() { constructor() {
this.registerAnimation('reveal', menuRevealAnimation); this.registerAnimation('reveal', menuRevealAnimation);
@ -134,6 +135,8 @@ export class MenuController implements MenuControllerI {
return undefined; return undefined;
} }
} }
await this.waitUntilReady();
if (menuId === 'start' || menuId === 'end') { if (menuId === 'start' || menuId === 'end') {
// there could be more than one menu on the same side // there could be more than one menu on the same side
// so first try to get the enabled one // so first try to get the enabled one
@ -166,24 +169,27 @@ export class MenuController implements MenuControllerI {
* Returns the instance of the menu already opened, otherwise `null`. * Returns the instance of the menu already opened, otherwise `null`.
*/ */
@Method() @Method()
getOpen(): Promise<HTMLIonMenuElement | undefined> { async getOpen(): Promise<HTMLIonMenuElement | undefined> {
return Promise.resolve(this.getOpenSync()); await this.waitUntilReady();
return this.getOpenSync();
} }
/** /**
* Returns an array of all menu instances. * Returns an array of all menu instances.
*/ */
@Method() @Method()
getMenus(): Promise<HTMLIonMenuElement[]> { async getMenus(): Promise<HTMLIonMenuElement[]> {
return Promise.resolve(this.getMenusSync()); await this.waitUntilReady();
return this.getMenusSync();
} }
/** /**
* Returns true if any menu is currently animating. * Returns true if any menu is currently animating.
*/ */
@Method() @Method()
isAnimating(): Promise<boolean> { async isAnimating(): Promise<boolean> {
return Promise.resolve(this.isAnimatingSync()); await this.waitUntilReady();
return this.isAnimatingSync();
} }
@Method() @Method()
@ -264,4 +270,11 @@ export class MenuController implements MenuControllerI {
} }
return undefined; return undefined;
} }
private waitUntilReady() {
return Promise.all(
Array.from(this.doc.querySelectorAll('ion-menu'))
.map(menu => menu.componentOnReady())
);
}
} }

View File

@ -31,7 +31,7 @@ export interface MenuControllerI {
_unregister(menu: MenuI): void; _unregister(menu: MenuI): void;
_setActiveMenu(menu: MenuI): void; _setActiveMenu(menu: MenuI): void;
getMenusSync(): HTMLIonMenuElement[]; getMenus(): Promise<HTMLIonMenuElement[]>;
getOpenSync(): HTMLIonMenuElement | undefined; getOpenSync(): HTMLIonMenuElement | undefined;
} }

View File

@ -168,7 +168,7 @@ export class Menu implements ComponentInterface, MenuI {
let isEnabled = !this.disabled; let isEnabled = !this.disabled;
if (isEnabled) { if (isEnabled) {
const menus = this.menuCtrl!.getMenusSync(); const menus = await this.menuCtrl!.getMenus();
isEnabled = !menus.some((m: any) => { isEnabled = !menus.some((m: any) => {
return m.side === this.side && !m.disabled; return m.side === this.side && !m.disabled;
}); });