Can Angular 2 parse links received from external CMS to be resolved as internal

独自空忆成欢 提交于 2019-12-11 02:57:44

问题


We are working on a decoupled project with Drupal as our backend and Angular as our front-end. Everything is nearing completion but certain (dynamic, as in created in Drupal) pages require links to different pages of the angular app.

For example:

  1. An editor creates an FAQ question in Drupal with an answer containing a link to the Pricing page of the angular app. (Q: How much does this service cost? A: Check out our [pricing] page)
  2. User on frontend opens FAQ page
  3. Angular loads our FAQ page (html) from Drupal via REST
  4. User clicks link mentioned in step 1

What happens:

The entire page gets reloaded, losing any processes that were currently going on (i.e. content playing in a player), and having the user look at our loading screen for a bit again.

What we would like to happen:

We would like to trigger the router to go to an internal URL so we don't lose our SPA feeling. We have tried to replicate this by using Dynamic Components, but since we have no idea before hand what the content looks like it's hard to implement this.

Is there an official way (or workaround perhaps) to fix this ? We imagined we could do it by either parsing any links we get from our CMS, or making a custom formatting in our CKeditor to parse. But once we get to the angular side, we don't know how we should insert our HTML with the links now working internally.


回答1:


It's been a while since you posted but I didn't find a solution myself so wanted to create this as a future reference.

We solved this problem by using a Directive that we use on the html like so:

<div [innerHTML]='contentFromCMS' appRouteDirective></div>

The Directive captures all clicks and checks if the target is an tag with a href element. If the href is relative, use the router. If it contains hostname (set your own) it gets the path and uses the router. Otherwise it opens in a new window.

import { Directive, ElementRef, HostListener } from '@angular/core';
import { Router } from '@angular/router';

declare let window: any;
declare let document: any;

@Directive({
  selector: '[appRouteDirective]'
})
export class RouterLinkDirective {
  public hostname = '.hygglo.se'; // The starting dot avoids email links as well

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

  @HostListener('click', ['$event'])
  public onClick(e) {
    const href = e.target.getAttribute('href');
    if (e.target.tagName === 'A' && href) {
      e.preventDefault();
      if (this.isLocalLink(href)) {
        this.router.navigate([this.getPathFromURL(href)]);
      } else {
        window.open(e.target.href);
      }
    }
  }

  public getPathFromURL(url: string) {
    let el = document.createElement('a');
    el.href = url;
    return el.pathname;
  }

  public isLocalLink(uri: string) {
    if (uri && (uri.startsWith('/') || uri.includes(this.hostname))) {
      return true;
    } else {
      return false;
    }
  }
}


来源:https://stackoverflow.com/questions/46427502/can-angular-2-parse-links-received-from-external-cms-to-be-resolved-as-internal

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!