将链接amphtml附加到角应用程序中

时间:2018-01-19 19:56:52

标签: angular angular5 amp-html angular-universal

我有一个有效的角度通用应用程序,我有一个特定页面的放大器版本。 要使放大器页面可访问,我必须添加到页面的<head>此标记

<link rel="amphtml" href="https://www.example.com/url/to/amp/document.html">

所以我需要类似于MetaService的东西。

我的问题是如何在angular 5 app的特定组件中执行此操作?

2 个答案:

答案 0 :(得分:4)

此类服务的更简洁版本是:

import { Inject, Injectable } from '@angular/core';
import { DOCUMENT } from '@angular/common';

@Injectable()
export class LinkService {

  constructor(@Inject(DOCUMENT) private doc) { }

  createLink() {
    let link: HTMLLinkElement = this.doc.createElement('link');
    link.setAttribute('rel', 'amphtml');
    link.setAttribute('href', 'https://www.example.com/url/to/amp/document.html');
    this.doc.head.appendChild(link);
  }
}

来源:https://www.concretepage.com/angular/angular-title-service-and-canonical-url

答案 1 :(得分:0)

我可以使用此评论https://github.com/angular/angular/issues/15776#issuecomment-352695731

中的代码创建服务

以下是此评论中的代码

/*
 * -- LinkService --        [Temporary]
 * @MarkPieszak
 * Added removeTag by @DominicBoettger
 * Similar to Meta service but made to handle <link> creation for SEO purposes
 * -- NOTE: Soon there will be an overall DocumentService within Angular that handles Meta/Link everything
 */

import { Injectable, Optional, RendererFactory2, ViewEncapsulation, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/platform-browser';

@Injectable()
export class LinkService {
  constructor(
    private rendererFactory: RendererFactory2,
    @Inject(DOCUMENT) private document
  ) {

  }

  /**
   * Inject the State into the bottom of the <head>
   */
  addTag(tag: LinkDefinition, forceCreation?: boolean) {

    try {
      const renderer = this.rendererFactory.createRenderer(this.document, {
        id: '-1',
        encapsulation: ViewEncapsulation.None,
        styles: [],
        data: {}
      });

      const link = renderer.createElement('link');

      const head = this.document.head;
      const selector = this._parseSelector(tag);

      if (head === null) {
        throw new Error('<head> not found within DOCUMENT.');
      }

      Object.keys(tag).forEach((prop: string) => {
        return renderer.setAttribute(link, prop, tag[prop]);
      });

      // [TODO]: get them to update the existing one (if it exists) ?
      renderer.appendChild(head, link);

    } catch (e) {
      console.error('Error within linkService : ', e);
    }
  }

  removeTag(attrSelector: string) {
    if (attrSelector) {
      try {
        const renderer = this.rendererFactory.createRenderer(this.document, {
          id: '-1',
          encapsulation: ViewEncapsulation.None,
          styles: [],
          data: {}
        });
        const head = this.document.head;
        if (head === null) {
          throw new Error('<head> not found within DOCUMENT.');
        }
        const linkTags = this.document.querySelectorAll('link[' + attrSelector + ']');
        for (const link of linkTags) {
          renderer.removeChild(head, link);
        }
      } catch (e) {
        console.log('Error while removing tag ' + e.message);
      }
    }
  }

  private _parseSelector(tag: LinkDefinition): string {
    // Possibly re-work this
    const attr: string = tag.rel ? 'rel' : 'hreflang';
    return `${attr}="${tag[attr]}"`;
  }
}

export declare type LinkDefinition = {
  charset?: string;
  crossorigin?: string;
  href?: string;
  hreflang?: string;
  media?: string;
  rel?: string;
  rev?: string;
  sizes?: string;
  target?: string;
  type?: string;
} & {
    [prop: string]: string;
  };