Search code examples
angularionic3innerhtmlangular2-directives

How to apply a directive to elements in innerHtml in angular 5?


This is for an Angular 5 / Ionic 3 application. I have a div where I display user generated html from a rich text editor:

<div [innerHtml]='text'></div>

This data can include <a href> links for which I need to capture the click event in order to force opening in the system's default browser.

I made a directive that works flawlessly for static content but will not affect anything inside the innerHtml element.

import { Directive, Input, HostListener } from "@angular/core";
import { InAppBrowser } from "@ionic-native/in-app-browser";

@Directive({
  selector : '[href]'
})
export class PreventLink {

  @Input() href;

  constructor( private iab: InAppBrowser ) {};

  @HostListener('click', ['$event'])
  public onClick( event: Event ) {

    if( event && this.href ) {

      if( this.href.length > 0 ){
        this.iab.create( this.href, '_system' );
      }

      event.preventDefault();
      return false;
    }
  };
};

Any ideas to achieve what I need would be appreciated.


Solution

  • I will post here my hacky solution if anyone wondered how to do it. I am still hoping for a better and more "angular" solution to achieve this.

    First we need to prepare a basic javascript snippet in index.html to find out when anchors are clicked. Place this at the end of the section.

    <script>
      document.onclick = function (e){
        e = e || window.event || {};
        var element = e.target || e.srcElement;
    
        if (element && element.tagName == 'A') {
    
          handleAClick( element.href );
    
          e.preventDefault();
          return false;
        }
      };
    
      function handleAClick(){}; //Just a placeholder until the angular app is ready
    </script>
    

    Then in app.component.ts I will override the handleAClick function with the real deal:

    import { Component, OnInit, ViewChild } from '@angular/core';
    import { InAppBrowser } from '@ionic-native/in-app-browser';
    import { Platform } from 'ionic-angular';
    
    
    @Component({
      templateUrl: 'app.html'
    })
    
    export class MySuperApp implements OnInit {
    
      constructor( private platform: Platform, private iab: InAppBrowser ){};
    
      ngOnInit() {
    
        this.platform.ready().then( () => {
    
          let win = (<any>window);
          win.handleAClick = ( url: string ) => {
            this.handleAClick( url );
          };
        });
      };
    
    
      private handleAClick( href: string ) {
    
        if( href && href.length > 0 ) {
          this.iab.create( href, '_system' );
        }
      };
    };