Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 9 never calls HammerGestureConfig.buildHammer

After update to Angular 9 it does not work to use Hammer.js anymore. We have extended the Angular HammerGestureConfig like the following.:

import {HammerGestureConfig} from '@angular/platform-browser';
import {Injectable} from '@angular/core';

@Injectable({providedIn: 'root'})
export class HammerConfig extends HammerGestureConfig {

  overrides = <any>{
    'pan': {
      direction: Hammer.DIRECTION_ALL,
      threshold: 5
    } // override default settings
  };

  buildHammer(element) {
    const recognizers = [];
    if (element.hasAttribute('data-hammer-pan')) {
      recognizers.push([Hammer.Pan]);
    }
    if (element.hasAttribute('data-hammer-pan-x')) {
      recognizers.push([Hammer.Pan, {direction: Hammer.DIRECTION_HORIZONTAL}]);
    }
    if (element.hasAttribute('data-hammer-tap')) {
      recognizers.push([Hammer.Tap]);
    }
    if (element.hasAttribute('data-hammer-pinch')) {
      recognizers.push([Hammer.Pinch]);
    }
    if (element.hasAttribute('data-hammer-rotate')) {
      recognizers.push([Hammer.Rotate]);
    }
    if (element.hasAttribute('data-hammer-press')) {
      recognizers.push([Hammer.Press]);
    }
    if (element.hasAttribute('data-hammer-swipe')) {
      recognizers.push([Hammer.Swipe]);
    }
    const hammer = new Hammer.Manager(element, {
      recognizers: recognizers,
      touchAction: 'auto'
    });
    return hammer;
  }
}

The HammerConfig is added to the app module.:

  providers: [
    {
      provide: HAMMER_GESTURE_CONFIG,
      useClass: HammerConfig
    }
  ],

As far as I understand the method buildHammer should be called, but it is never called.

What could be the problem?

like image 940
BuZZ-dEE Avatar asked Feb 24 '20 16:02

BuZZ-dEE


2 Answers

The HammerModule needs to be imported to the Angular app module.

  imports: [
    ...
    HammerModule
  ],
  providers: [
    {
      provide: HAMMER_GESTURE_CONFIG,
      useClass: HammerConfig
    },
    ...
  ],
  ...

ivy: make Hammer support tree-shakable. Previously, in Ivy applications, Hammer providers were included by default. With this commit, apps that want Hammer support must import HammerModule in their root module. (#32203) (de8ebbd)

https://github.com/angular/angular/blob/9.0.0/CHANGELOG.md

like image 62
BuZZ-dEE Avatar answered Sep 17 '22 23:09

BuZZ-dEE


Comment out any imports for hammerjs that are likely in your main.ts file that were likely added in Angular 8 or earlier -- for me it was originally an Angular 4 project 2 years old that we have evolved. But Angular 9 can't use it there.

Move them all to app.module.ts in this order…

import { HammerModule, HammerGestureConfig, HAMMER_GESTURE_CONFIG } from '@angular/platform-browser';
declare var Hammer: any;

If you are using it for swipes, like for a carousel, you will need to export a custom class...

@Injectable()
export class MyHammerConfig extends HammerGestureConfig {
  overrides = <any>{
    pan: { direction: Hammer.DIRECTION_All },
    swipe: { direction: Hammer.DIRECTION_VERTICAL },
  }

  buildHammer(element: HTMLElement) {
    const mc = new Hammer(element, {
      touchAction: 'auto',
      inputClass: Hammer.SUPPORT_POINTER_EVENTS ? Hammer.PointerEventInput : Hammer.TouchInput,
      recognizers: [
        [
          Hammer.Swipe,
          {
            direction: Hammer.DIRECTION_HORIZONTAL,
          },
        ],
      ],
    })
    return mc
  }
}

Then in NgModule

@NgModule({
// ...
   imports: [
      HammerModule,
      // ...

don't forget the providers...

providers: [
 {provide: HAMMER_GESTURE_CONFIG, useClass: MyHammerConfig}
  // ...
] 

It should work.

like image 33
AppDreamer Avatar answered Sep 21 '22 23:09

AppDreamer