Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular routerLink within [innerHTML]

I have been looking around for a way to enable standard a[href] links to act like routerLinks when loaded dynamically into [innerHTML]. It doesn't seem to be something that works as standard and I couldn't find anything that did what I needed.

I have a working solution but wondered if anybody knows of any better ways to do this or any potential issues I might run into doing it this way.

I am using jQuery from inside my app-routing.module.ts so I declare the variable:

declare var $:any;

I then find all anchors with the href attribute that do not also have the routerlink attribute. I can then grab the pathname and tell the router to navigate to it on click.

$(document).on('click', `a[href]:not("a[routerlink]"):not("a[href^='mailto:']"):not("a[href^='tel:']")`, function(e){
    if(location.hostname === this.hostname || !this.hostname.length){
        e.preventDefault();
        router.navigate([this.pathname]);
    }
});

This seems to do the job but I thought there must be a more 'Angular' way of doing this...

like image 688
Steve Avatar asked Aug 17 '17 14:08

Steve


People also ask

Can we use href instead of routerLink?

In this case since they are served at two different base urls(in this case for dev environment its localhost:4201 && localhost:4202) using router link will not actually route you to the other base route location. Using href is required or it will fail routing you to the correct url.

What is difference between routerLink and routerLink?

What is the difference between [routerLink] and routerLink ? How should you use each one? They're the same directive. You use the first one to pass a dynamic value, and the second one to pass a static path as a string.

Can I use routerLink on Div?

Angular 2+ Yes it can be attached to div tag, your route is probably wrong try add / in front of route.

Can we pass object in routerLink?

RouterLink for dynamic dataDynamic data or user-defined objects can be passed from Angular version 7.2 using the state object stored in History API. The state value can be provided using the routerLink directive or navigateByURL.


1 Answers

This may not be the best way to do it, but you can use Renderer and ElementRefto add an event listener to the anchor tags as is discussed in this article.


@Component({
  selector: 'app-example-html',
  templateUrl: './example.component.html',
  styleUrls: ['./example.component.less'],
})
export class ExampleComponent implements AfterContentInit {

  private clickListeners: Array<(evt: MouseEvent) => void> = [];

  constructor(
    private router: Router,
    private el: ElementRef,
    private renderer: Renderer2,
  ) { }

  ngAfterViewInit() {
    const anchorNodes: NodeList = this.el.nativeElement.querySelectorAll('a[href]:not(.LinkRef)'); // or a.LinkPage

    const anchors: Node[] = Array.from(anchorNodes);

    for (const anchor of anchors) {
      // Prevent losing the state and reloading the app by overriding the click event
      const listener = this.renderer.listen(anchor, 'click', (evt: MouseEvent) => this.onLinkClicked(evt));
      this.clickListeners.push(listener);
    }
  }

  private onLinkClicked(evt: MouseEvent) {
    evt.preventDefault();
    if (evt.srcElement) {
      const href = evt.srcElement.getAttribute('href');
      if (href) {
        this.router.navigateByUrl(href);
      }
    }
  }
}


like image 194
Ryan Kara Avatar answered Sep 28 '22 12:09

Ryan Kara