Ionic-framework: [Beta.12] Add the registerAnimation in the menuController of angular

Created on 28 Sep 2018  路  8Comments  路  Source: ionic-team/ionic-framework

Feature Request

Ionic Info
Run ionic info from a terminal/cmd prompt and paste the output below.

Ionic:

   ionic (Ionic CLI)          : 4.1.2 (/usr/local/lib/node_modules/ionic)
   Ionic Framework            : @ionic/angular 4.0.0-beta.12
   @angular-devkit/core       : 0.8.2
   @angular-devkit/schematics : 0.8.2
   @angular/cli               : 6.1.2
   @ionic/ng-toolkit          : 1.0.8
   @ionic/schematics-angular  : 1.0.6

Cordova:

   cordova (Cordova CLI) : 8.0.0
   Cordova Platforms     : android 7.1.0, browser 5.0.4, ios 4.5.5
   Cordova Plugins       : cordova-plugin-ionic-keyboard 2.0.5, cordova-plugin-ionic-webview 1.1.1, (and 14 other plugins)

System:

   ios-deploy : 1.9.2
   NodeJS     : v10.10.0 (/usr/local/Cellar/node/10.10.0/bin/node)
   npm        : 6.4.1
   OS         : macOS High Sierra
   Xcode      : Xcode 10.0 Build version 10A255

Describe the Feature Request
First of all thank you for adding the registerAnimation in the @ionic/core menucontroller I was able to overwrite the menu animation without problems. ;)

Now...
It would be interesting to add to the menu controller the possibility to register animations for the menu. Currently I get it by overwriting the menuController in the app.module.ts by an own provider.

Describe Preferred Solution
As you can see I only use the proxyMethod something that already comes by default in the @ionic/angular menucontroller.

import { MenuController } from '@ionic/angular';
import { Injectable } from '@angular/core';

import { proxyMethod } from '@ionic/angular/dist/util/util';

const CTRL = 'ion-menu-controller';
@Injectable()
export class OverrideMenuController extends MenuController {
    registerAnimation(name, animation): Promise<boolean> {
        return proxyMethod(CTRL, 'registerAnimation', name, animation);
    }
}

In app.module.ts

@NgModule({
    ...
    imports: [
        IonicModule.forRoot({
            menuType: 'reveal-with-backdrop'
        }),
    ],
    providers: [
        ...
            { provide: MenuController, useClass: OverrideMenuController }
         ...
    ]
}];

In app.component.ts

constructor(
    public menuCtrl: MenuController
){
    this.platform.ready().then(() => {
        this.menuCtrl['registerAnimation']('reveal-with-backdrop', revealWithBackdropAnimation);
    });
}

Thanks.

feature request

Most helpful comment

Here's a quick workaround for angular. I got it to work by creating a new component which extends MenuController.

import { DOCUMENT } from '@angular/common';
import { Inject, Injectable } from '@angular/core';

import { MenuController } from '@ionic/angular';
import { AnimationBuilder } from '@ionic/core';

function proxyMethod(ctrlName: string, doc: Document, methodName: string, ...args: any[]) {
  const controller = ensureElementInBody(ctrlName, doc);
  return controller.componentOnReady()
    .then(() => (controller as any)[methodName].apply(controller, args));
}

function ensureElementInBody(elementName: string, doc: Document) {
  let element = doc.querySelector(elementName);
  if (!element) {
    element = doc.createElement(elementName);
    doc.body.appendChild(element);
  }
  return element as HTMLStencilElement;
}

const CTRL = 'ion-menu-controller';
@Injectable({
  providedIn: 'root',
})
export class EloMenuController extends MenuController {

  constructor(@Inject(DOCUMENT) private document: any) {
      super(document)
  }

  /**
   * Registers a new animation that can be used with any `ion-menu` by
   * passing the name of the animation in its `type` property.
   *
   * @param name The name of the animation to register.
   * @param animation The animation function to register.
   */
  registerAnimation(name: string, animation: AnimationBuilder) {
    return proxyMethod(CTRL, this.document, 'registerAnimation', name, animation);
  }
}

All 8 comments

Hello,
@Yomyer can you please explain to me how did you overwrite the menu animation in ionic 4, I have a menu with a 3D animation and I am unable to register my specific menu type.
Thank you in advance

Hello @manucorporat,

As @Yomyer said, thank you for adding the registerAnimation function in the @ionic/core/src/components/menu-controller/menu-controller.ts.

Is it possible to add to the MenuController of Angular and Vue the possibility to register animations for the menu without overwriting it.

Thanks a lot

registerAnimation function is still not available in version 4.3.1.
I have updated dependency

"@ionic/angular": "^4.3.1"

in my package.json but still no luck. can anyone suggest what i am doing wrong here ?

I'm on @ionic/angular 4.4.2 and the method still isn't available :(

Here's a quick workaround for angular. I got it to work by creating a new component which extends MenuController.

import { DOCUMENT } from '@angular/common';
import { Inject, Injectable } from '@angular/core';

import { MenuController } from '@ionic/angular';
import { AnimationBuilder } from '@ionic/core';

function proxyMethod(ctrlName: string, doc: Document, methodName: string, ...args: any[]) {
  const controller = ensureElementInBody(ctrlName, doc);
  return controller.componentOnReady()
    .then(() => (controller as any)[methodName].apply(controller, args));
}

function ensureElementInBody(elementName: string, doc: Document) {
  let element = doc.querySelector(elementName);
  if (!element) {
    element = doc.createElement(elementName);
    doc.body.appendChild(element);
  }
  return element as HTMLStencilElement;
}

const CTRL = 'ion-menu-controller';
@Injectable({
  providedIn: 'root',
})
export class EloMenuController extends MenuController {

  constructor(@Inject(DOCUMENT) private document: any) {
      super(document)
  }

  /**
   * Registers a new animation that can be used with any `ion-menu` by
   * passing the name of the animation in its `type` property.
   *
   * @param name The name of the animation to register.
   * @param animation The animation function to register.
   */
  registerAnimation(name: string, animation: AnimationBuilder) {
    return proxyMethod(CTRL, this.document, 'registerAnimation', name, animation);
  }
}

Hi,
@svallory I followed your implementation and it was working on ionic 4.7.0 after updating ionic to 4.11.x it is broken, menu controller now does not have constructor with document parameter that's why the menu now is undefined! can you please help?

Sorry @subhi-shuqier, I'm not working with ionic anymore and it would take quite some time to get up to speed again

Hi, did anyone find a ionic 5 fix to this problem?

Was this page helpful?
0 / 5 - 0 ratings