将链接 amphtml 附加到 Angular 应用程序的头部

Posted

技术标签:

【中文标题】将链接 amphtml 附加到 Angular 应用程序的头部【英文标题】:append link amphtml to head in angular app 【发布时间】:2018-06-29 03:19:45 【问题描述】:

我有一个可用的 Angular 通用应用程序,并且我有一个特定页面的 amp 版本。 为了使 amp 页面可以访问,我必须添加到页面的 <head> 这个标签

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

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

我的问题是如何在 Angular 5 应用程序的特定组件中执行此操作?

【问题讨论】:

【参考方案1】:

我可以通过使用此评论 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;
  ;

【讨论】:

【参考方案2】:

此类服务的更简洁版本如下:

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

@Injectable()
export class LinkService 

  constructor(@Inject(DOCUMENT) private doc: Document)  

  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

【讨论】:

以上是关于将链接 amphtml 附加到 Angular 应用程序的头部的主要内容,如果未能解决你的问题,请参考以下文章

Angular 4 错误消息应链接到无效的 formControl

将元素附加到 QueryList Angular

将图像文件附加到表单数据 - Cordova/Angular

Angular 2 将组件动态附加到 DOM 或模板

通过 Angular 4 将 JWT 令牌附加到 api 请求

如何在Angular 6的循环中链接承诺