简体   繁体   English

Angular 7:子域不可知路由器/ routerLink

[英]Angular 7: subdomain agnostic router / routerLink

I want to use URLs that use subdomains for usernames. 我想使用使用子域作为用户名的URL。 Eg the user 'joe' will get his own space at https://joe.example.com/ 例如,用户“ joe”将在https://joe.example.com/获得自己的空间

The 'www' subdomain will hold the functionality common to all users - eg signup or news or whatever. “ www”子域将拥有所有用户共有的功能-例如注册或新闻或其他。 My webserver responds to all *.example.com requests with the same content. 我的网络服务器以相同的内容响应所有* .example.com请求。 I want to create links from www.example.com to joe.example.com and vice versa like https://joe.example.com/myparam/myvalue 我想创建从www.example.com到joe.example.com的链接,反之亦然,例如https://joe.example.com/myparam/myvalue

Currently [routerLink]="['myparam', 'myvalue'] only creates links within the same subdomain. I need to add the subdomain somehow. 目前[routerLink]="['myparam', 'myvalue']仅在同一子域内创建链接,我需要以某种方式添加子域。

I know that the whole application has to be re-initialized with every subdomain change. 我知道整个应用程序都必须在每次子域更改时都重新初始化。 But I want to give it a try. 但我想尝试一下。

What is the best way to realize this using Angular 7? 使用Angular 7实现此目标的最佳方法是什么?

Thank you! 谢谢!

Best, Malte 最好,马尔特

I have created a directive vafLink that replaces the standard routerLink . 我创建了一个指令vafLink ,它替换了标准routerLink The first array element will be parsed as the target subdomain. 第一个数组元素将被解析为目标子域。 If it equals to the current subdomain, the standard angular router will be used to update the view. 如果它等于当前子域,则将使用标准角度路由器更新视图。 Otherwise the window.location.href will be changed to the target URL and the browser loads the new subdomain and its content. 否则, window.location.href将更改为目标URL,并且浏览器将加载新的子域及其内容。

Here is the code (be careful, I'm new to Angular - started three days ago): 这是代码(请注意,我是Angular的新手,三天前开始):

import { Directive, OnChanges, HostBinding, Input, HostListener } from '@angular/core';
import { Router } from '@angular/router';
import { SubdomainService } from './subdomain.service';
import { environment } from '../environments/environment';

@Directive({
  selector: ':not(a):not(area)[vafLink]'
})
export class VaflinkDirective implements OnChanges {
  private commands: any[] = [];
  private href: string;
  @Input() fragment !: string;

  constructor(
    private router: Router,
    private subdomain: SubdomainService) { }

  @Input()
  set vafLink(commands: any[]|string) {
    if (commands != null) {
      this.commands = Array.isArray(commands) ? commands : [commands];
    } else {
      this.commands = [];
    }
  }

  ngOnChanges(changes: {}): any { this.updateTargetUrlAndHref(); }

  private updateTargetUrlAndHref(): void {
    if (this.commands.length == 0) {
      this.href = 'https://' + this.subdomain.getSubdomain() + '.' + environment.Domain + '/'
      return;
    }

    this.href = 'https://' + this.commands[0] + '.' + environment.Domain + '/' + this.commands.slice(1, this.commands.length).join('/');
    if (this.fragment) {
      this.href += '#' + this.fragment;
    }
  }

  @HostListener('click')
  onClick(): boolean {
    if (this.commands.length == 0) {
      this.router.navigate([], {fragment: this.fragment});
      return false;
    }

    if (this.subdomain.getSubdomain() != this.commands[0]) {
      window.location.href = this.href;
    } else {
      this.router.navigate(this.commands.slice(1, this.commands.length), {fragment: this.fragment});
    }
    return false;
  }
}


@Directive({
  selector: 'a[vafLink],area[vafLink]'
})
export class VaflinkDirectiveWithHref implements OnChanges {
  @HostBinding() href !: string;
  @Input() fragment !: string;

  private commands: any[] = [];

  constructor(
    private router: Router,
    private subdomain: SubdomainService) { }

  @Input()
  set vafLink(commands: any[]|string) {
    if (commands != null) {
      this.commands = Array.isArray(commands) ? commands : [commands];
    } else {
      this.commands = [];
    }
  }

  ngOnChanges(changes: {}): any { this.updateTargetUrlAndHref(); }

  private updateTargetUrlAndHref(): void {
    if (this.commands.length == 0) {
      this.href = 'https://' + this.subdomain.getSubdomain() + '.' + environment.Domain + '/'
      return;
    }

    this.href = 'https://' + this.commands[0] + '.' + environment.Domain + '/' + this.commands.slice(1, this.commands.length).join('/');
    if (this.fragment) {
      this.href += '#' + this.fragment;
    }
  }

  @HostListener('click', ['$event.button', '$event.ctrlKey', '$event.metaKey', '$event.shiftKey'])
  onClick(button: number, ctrlKey: boolean, metaKey: boolean, shiftKey: boolean): boolean {
    if (this.commands.length == 0) {
      this.router.navigate([], {fragment: this.fragment});
      return false;
    }

    if (this.subdomain.getSubdomain() != this.commands[0]) {
      window.location.href = this.href;
      return true;
    } else {
      this.router.navigate(this.commands.slice(1, this.commands.length), {fragment: this.fragment});
    }
    return false;
  }
}

This code is an adaption of the original routerLink code. 该代码是原始routerLink代码的改编。 The implementation misses a few features the original routerLink has. 该实现错过了原始routerLink具有的一些功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM