我正在try 将Google Analytics与angular 4结合使用,但在ts中找不到任何指向ga.js的@type.

为了快速解决问题,我在每个组件中都使用了这一点:

declare let ga: any;

下面是我如何解决的:

创建一个函数动态加载GA,插入带有当前trackingId和用户的GA脚本.

    loadGA(userId) {
        if (!environment.GAtrackingId) return;

        let scriptId = 'google-analytics';

        if (document.getElementById(scriptId)) {
            return;
        }

        var s = document.createElement('script') as any;
        s.type = "text/javascript";
        s.id = scriptId;
        s.innerText = "(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');ga('create', { trackingId: '" + **environment.GAtrackingId** + "', cookieDomain: 'auto', userId: '" + **userId** + "'});ga('send', 'pageview', '/');";

        document.getElementsByTagName("head")[0].appendChild(s);
    }

创建服务以实现所需的方法.

import { Injectable } from '@angular/core';
import { environment } from '../../../environments/environment';

declare let ga: any;

@Injectable()
export class GAService {
    constructor() {
    }

    /**
     * Checks if the GA script was loaded.
     */
    private useGA() : boolean { 
        return environment.GAtrackingId && typeof ga !== undefined;
    }

    /**
     * Sends the page view to GA.
     * @param  {string} page The path portion of a URL. This value should start with a slash (/) character.
     */
    sendPageView(
        page: string
    ) {
        if (!this.useGA()) return;
        if (!page.startsWith('/')) page = `/${page}`;      
        ga('send', 'pageview', page);
    }


    /**
     * Sends the event to GA.
     * @param  {string} eventCategory Typically the object that was interacted with (e.g. 'Video')
     * @param  {string} eventAction The type of interaction (e.g. 'play')
     */
    sendEvent(
        eventCategory: string,
        eventAction: string
    ) { 
        if (!this.useGA()) return;
        ga('send', 'event', eventCategory, eventAction);
    }
}

然后我最终使用注入组件中的服务.

constructor(private ga: GAService) {}

ngOnInit() { this.ga.sendPageView('/join'); }

推荐答案

首先,你需要在你的电脑中安装谷歌分析的打字功能

npm install --save-dev @types/google.analytics

然后在基数index.html中添加跟踪代码,并删除最后一行,如下所示:

<body>
  <app-root>Loading...</app-root>
  <script>
    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
        (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
      m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
    })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

    ga('create', 'UA-XXXXXX-ID', 'auto');  // <- add the UA-ID 
                                           // <- remove the last line 
  </script>
</body>

下一步包括更新主组件构造函数以进行事件跟踪.

constructor(public router: Router) {
    this.router.events.subscribe(event => {
      if (event instanceof NavigationEnd) {
        ga('set', 'page', event.urlAfterRedirects);
        ga('send', 'pageview');
      }
    });
  }

如果您想跟踪某个特定事件,还可以创建一个服务,并将其注入到任何要实现事件跟踪的组件中.

// ./src/app/services/google-analytics-events-service.ts

import {Injectable} from "@angular/core";

@Injectable()
export class GoogleAnalyticsEventsService {

  public emitEvent(eventCategory: string,
                   eventAction: string,
                   eventLabel: string = null,
                   eventValue: number = null) {
    ga('send', 'event', { eventCategory, eventLabel, eventAction, eventValue });
  }
}

例如,如果你想在你的主组件上点击鼠标,你所需要做的就是注入GoogleAnalyticsEventsService并调用emitEvent()方法.

更新的home组件源代码:

constructor(public router: Router, public googleAnalyticsEventsService: GoogleAnalyticsEventsService) {
    this.router.events.subscribe(event => {
      if (event instanceof NavigationEnd) {
        ga('set', 'page', event.urlAfterRedirects);
        ga('send', 'pageview');
      }
    });
  }
  submitEvent() { // event fired from home.component.html element (button, link, ... )
    this.googleAnalyticsEventsService.emitEvent("testCategory", "testAction", "testLabel", 10);
  }

Typescript相关问答推荐

TypScript中的算法运算式

Angular 17 -如何在for循环内创建一些加载?

动态判断TypScript对象是否具有不带自定义类型保护的键

根据另一个属性的值来推断属性的类型

更新为Angular 17后的可选链运算符&?&问题

如何使用Zod使一个基于其他字段值的字段为必填字段?

STypescript 件的标引签名与功能签名的区别

分解对象时出现打字错误

是否可以针对联合类型验证类型属性名称?

如何在Typescript 中组合unions ?

在Mac和Windows上运行的Web应用程序出现这种对齐差异的原因是什么?(ReactNative)

有没有办法防止类型交集绕过联合类型限制?

创建Angular 为17的动态形状时出错

复选框Angular 在Ngfor中的其他块中重复

Typescript -返回接口中函数的类型

递归类型名称

有没有办法从不同长度的元组的联合中提取带有类型的最后一个元素?

如何在 ngFor 循环中以Angular 正确动态渲染组件

如何将参数传递给条件函数类型

创建通过删除参数来转换函数的对象文字的类型