Search code examples
angularionic-frameworkhammer.js

Can't bind data with hammerjs


I'm sliding on screen and getting x coordinate with hammerjs and on same time I'm trying to view the value of x on HTML template through data binding. As I slide, the value of x is changing in console but that value is not shown on HTML view. The value of x (on HTML view) is changed only when I stop sliding and touch the screen again.

HTML

<ion-content id="ion-content">
  <div>
    x: {{x}}
  </div>
</ion-content>

TS

const ionContent = document.getElementById('ion-content');
const mc = new Hammer.Manager(ionContent);
const pan = new Hammer.Pan();
mc.add([pan]);
mc.get('pan').set({enable: true});
mc.on('pan', ev => {
  this.x = ev.center.x;
  console.log('x: ', this.x);
});

Note: I'm facing this issue in latest version of ionic-angular (in android using capacitor plugin)


Solution

  • The on callback from HammerJS is probably being executed outside of Angular's zones, which means that Angular doesn't know that the view should be updated.

    In order to fix this, you'd need to tell Angular that something has been changed and the view needs to be updated:

      import { Component, Inject, NgZone, ... } from '@angular/core';
    
      // ...
    
      constructor(private ngZone: NgZone) { ... }
    
      // ...
    
      mc.on('pan', ev => {
        this.ngZone.run(() => {  // <-- like this!
          this.x = ev.center.x;
          console.log('x: ', this.x);
        });
      });
    

    Please keep in mind that updating the view could be an expensive operation so only use zones when you really need to update the view (maybe you don't want to show in the view every pan event but only the last one for example).

    You can find more information about zones in the Angular docs or in this super helpful blog post.