角度2环境特定头部注射

时间:2017-03-07 19:13:19

标签: javascript angular environment-variables google-tag-manager angular-cli

我为我的Angular2应用程序添加了Google跟踪代码管理器支持,我不知道如何为开发与生产注入所需的不同容器ID所需的GTM脚本,因为我有两个GTM中的容器。

有没有办法注入head标签并根据环境文件中的变量更改容器ID?

我在构建过程中使用Angular CLI。

1 个答案:

答案 0 :(得分:0)

您可以为Tag Manager构建一个服务,我自己为我的公司项目构建了一个服务,该项目为AdWordsGoogle Trusted StoresAnalytics等提供商处理多个容器ID和事件。

这是注入标记管理器脚本的模型的示例版本。 (注意:由于直接使用documentwindow,因此无法通用。)

export class TagManager {
private static instance: TagManager = null;
private ids: string[];
private dataLayerName: string;
private precision: number = 2;

public dataLayer: any[] = [];
public language: string;
public currency: string;

constructor(ids: string[], dataLayerName: string, language: string, currency: string) {
  if(TagManager.instance) {
    throw new Error("Error - use GoogleTagManager.getInstance()");
  }
  this.ids = ids;
  this.dataLayerName = dataLayerName;
  this.currency = currency;
  this.language = language;
  this.init();
}

private init() {
  this.ids.forEach(id => this.initContainer(id));
}

private initContainer(id: string) {
  let internal = this;
  (function(w,d,s,l,i) {
    w[l]=w[l]||[];
    w[l].push({
      'gtm.start': new Date().getTime(),
       event:'gtm.js'
    });
    let f: any = d.getElementsByTagName(s)[0];
    let j: any = d.createElement(s);
    let dl: any = l!='dataLayer'?'&l='+l:'';
    j.async=true;
    j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;
    f.parentNode.insertBefore(j,f);
    internal.dataLayer = w[l];
  })(window,document,'script',this.dataLayerName,id);
}

public static getInstance(ids: string | string[] = [], dataLayerName = 'dataLayer', language = 'en', currency = 'EUR') {
    ids = ids || [];
    ids = Array.isArray(ids)? ids: [ids];
    if(!TagManager.instance) {
      if(ids.length === 0) {
        return;
      }
      ids.forEach(id => {
        if(!id || (typeof id !== 'string') || id.indexOf('GTM-') !== 0) {
          console.error("Please provide a valid container ID (i.e. GTM-XXXXXX)");
        }
      })
      if(!dataLayerName || (typeof dataLayerName !== 'string')) {
        console.error("Please provide a valid name for the data layer");
      }
   }
   TagManager.instance = TagManager.instance || new TagManager(ids,   dataLayerName, language, currency);
   return TagManager.instance;
  }
}

服务示例:

@Injectable()
export class Service {
  private static instance: TagManager = null;
  private eventTracker$: ReplaySubject<any> = new ReplaySubject();
  private dataStream$: ReplaySubject<any> = new ReplaySubject();
  private currency: string;
  private precision: number = 3;
  private language: string;

  private readyTracker$: ReplaySubject<boolean> = new ReplaySubject<boolean>();

  public get settings() {
    return {
      language: this.language,
      currency: this.currency,
      precision: this.precision
    }
  }

  public get eventTrack$() {
    return this.eventTracker$.asObservable();
  }

  public get dataLayer$() {
    return this.dataStream$.asObservable();
  }

  public get isReady$() {
    return this.readyTracker$.asObservable();
  }

  public get isInitialized() {
    return !!Service.instance;
  }

  constructor() {
    this.readyTracker$.next(false);
  }

  public init(containerIds?: string[], dataLayerName?: string, language?: string, currency?: string) {
    if(Service.instance instanceof TagManager) {
      console.error('Google tag manager already loaded.');
      return;
    }
    Service.instance = TagManager.getInstance(containerIds || [], dataLayerName || 'dataLayer', language || 'en', currency || 'EUR');
    this.currency = currency;
    this.language = language;
    if(!Service.instance) {
      console.info('no gtm container installed');
      return;
    }
    this.dataLayer$.subscribe(e => {
      Service.instance.dataLayer.push(e);
    });
    this.readyTracker$.next(true);
  }

  public push(data: any) {
    this.dataStream$.next(data);
  }

  public pushCustomEvent(eventName: string, attributes: any) {
    this.push({
      event: eventName,
      attributes: attributes
    });
  }

  public pushEcommerceEvent(eventName: string, eventData: any) {
    this.push(Object.assign({}, {
      event: eventName
    }, eventData))
  }
}

AdWords提供商示例:

@Injectable()
export class AdwordsProvider {
  constructor(private gtmService: Service) { }

  public sendConversion(id: string, value: number) {
    // build conversion 
    let conversion = {
      [Fields.Conversion.attributes.id]: id,
      [Fields.Conversion.attributes.value]: Number.parseFloat(value.toFixed(this.gtmService.settings.precision)).toString(),
      [Fields.Conversion.attributes.currency]: this.gtmService.settings.currency
    };
    // push event to dataLayer
    this.gtmService.pushCustomEvent('conversionEventName', {
     // event data
    });
  }
}

或者你可以看一下angulartics2,也许它符合你的需要。