farcasmihai91
4/20/2018 - 7:52 PM

Angular - Custom Directive

@Component({
  selector: 'app-paywall-directive-widget',
  templateUrl: './paywall-directive-widget.component.html',
  styleUrls: ['./paywall-directive-widget.component.css']
})
export class PaywallDirectiveWidgetComponent implements IWidget, AfterViewInit {
  widgetTitle = 'Paywall Directive';
  // declared Typescript interface inline
  linkList: {title: string, licenseLevel: number}[] = [];

  ngAfterViewInit(): void {
    for (let i = 0; i < 10; i++) {
      this.linkList.push({
        title: `Link # ${i + 1}`,
        licenseLevel: Math.floor((Math.random() * 3) + 1)
      });
    }
  }
}

// the component template
// <ul>
//   <li class="link" *ngFor="let item of linkList">
//     <a href="#" hsPaywall [requiredLicense]="item.licenseLevel" >{{item.title}}</a>
//   </li>
// </ul>

// The actual directive
@Directive({
  selector: '[appPaywall]'
})
export class PaywallDirective implements OnInit {
  @Input() requiredLicense: number;
  elm: HTMLElement;

  constructor(element: ElementRef, private ren: Renderer2, private cfg: LicenseConfigService) {
    if (element && element.nativeElement) {
      this.elm = element.nativeElement;
    }
  }

  // Programatically add HTML using Renderer2
  private checkLink(element: HTMLAnchorElement) {
    // check required license
    if (this.requiredLicense > this.cfg.currentLicense) {
      const span = this.ren.createElement('span');
      this.ren.addClass(span, 'paywall');
      span.title = 'Requires additional license purchase';
      const txt = this.ren.createText('[$]');
      this.ren.appendChild(span, txt);
      const parent = this.ren.parentNode(element);
      this.ren.appendChild(parent, span);
    }
  }

  ngOnInit(): void {
    if (this.elm && this.elm instanceof HTMLAnchorElement) {
      this.checkLink(this.elm as HTMLAnchorElement);
    }
  }
}