1

Similar question has been asked multiple times but I cannot get this to work. For example here is some answers that don't work for most people. This might not be angular issue per se, but I'm trying to solve this in ng app.

I want link to work normal when clicked. In addition i want the item that contains the link to be doubleclickable to open the link to split-area on side of router-outlet. So in my navigation-menu I have:

    <li *ngIf="propertiesTabVisible"  class="nav-item tab-nav-item"
      [routerLinkActive]='["link-active"]' [routerLinkActiveOptions]='{ exact: true }' 
      (dblclick)="toggleTab('/properties/' + sessionId)">
      <a class="nav-link" [routerLink]='["/properties", sessionId]'
       [class.disabled]="(propertiesLinkDisabled | async)"
       (click)="navigateWithDelay('/properties/' +sessionId)">
        <mat-icon class="tab-nav-item-icon">assignment</mat-icon>
      </a>
    </li>

and in component.ts:

  private block = true;
  private isCancelled = false;

  private delay(ms: number) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }

  private async sleepExample(url: string) {
    await this.delay(200);
    if (!this.block) {
      this.router.navigate([url]);
    }
  }

  navigateWithDelay(url: string) :boolean {
    this.block = true;
    this.isCancelled = false;
    this.sleepExample(url).then(() => {
      if (!this.isCancelled) {
        this.block = false;
      }
    });
    return false;
  }

  toggleTab(url: string) {
    this.isCancelled = true;
    toggleTabVisibility(url);
  }

However this does not work. Even though both handlers are called and they function as I expected on top of that router outlet works so the navigation happens. How to prevent link click propagation in click-hanlder?

char m
  • 7,840
  • 14
  • 68
  • 117
  • 1
    Can't you call `$event.stopPropagation()`? Like [here](https://stackoverflow.com/questions/35274028/stop-mouse-event-propagation) – Korfoo Jun 11 '19 at 12:53
  • Thanks for your comment, but I didn't get that to work. Maybe my syntax was wrong or something. – char m Jun 11 '19 at 13:02
  • oh, actually i didn't. I have to try this directive approach. – char m Jun 11 '19 at 13:02
  • 1
    It's not an Angular issue, take a look at this: https://stackoverflow.com/questions/5497073/how-to-differentiate-single-click-event-and-double-click-event – Mehdi Benmoha Jun 11 '19 at 13:18
  • As I wrote in the question both click and dblclick handlers are called so not that question @Mehdi . I need single click to react to my single click event AND NOT default behavior which is navigate the link – char m Jun 12 '19 at 07:02
  • @MehdiBenmoha: This is very much Angular related. See https://github.com/angular/angular/issues/21457. – char m Jun 12 '19 at 11:12
  • Then don’t put routerLink and handle your routing in the component.ts – Mehdi Benmoha Jun 12 '19 at 12:44
  • I already solved this. Will write answer when I know best solution. – char m Jun 12 '19 at 13:25

1 Answers1

0

The reason $event.stopPropagation() and ;$event.preventDefault() are not working in routerLink is described here.

Here is working example where click event is moved in mat-icon inside anchor and handler calls both:

    $event.stopPropagation();
    $event.preventDefault();

.html:

<li *ngIf="propertiesTabVisible"  class="nav-item tab-nav-item" [routerLinkActive]='["link-active"]' [routerLinkActiveOptions]='{ exact: true }'
(dblclick)="toggleTab('/properties/' +sessionId)">
  <a class="nav-link" [routerLink]='["/properties", sessionId]' [class.disabled]="(propertiesLinkDisabled | async)">
    <mat-icon class="tab-nav-item-icon" (click)="navigateWithDelay($event, '/properties/' +sessionId)">assignment</mat-icon>
  </a>
</li>

.ts:

  toggleTab(url: string) {
    this.isCancelled = true;
    this.ngRedux.dispatch(this.actions.toggleWindowUrl({
      windowId: this.tabService.windowId,
      url: url,
      isSplit: true
    }));
  }

  private isCancelled = false;

  private delay(ms: number) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }

  private async waitForDoubleClick() {
    await this.delay(200);
  }

  navigateWithDelay($event: any, url: string) {
    this.isCancelled = false;
    $event.stopPropagation();
    $event.preventDefault();
    this.waitForDoubleClick().then(() => {
      if (!this.isCancelled) {
        this.router.navigate([url]);
      }
    });
  }
char m
  • 7,840
  • 14
  • 68
  • 117