我需要在 Angular 项目中实现 Facebook 像素。我的 index.html
中有来自 src/index.html
<!doctype html>
<html lang="en">
<head>
.....
</head>
<body>
<app-root></app-root>
<!-- Facebook Pixel Code -->
<script>
!function(f,b,e,v,n,t,s)
{if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};
if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];
s.parentNode.insertBefore(t,s)}(window, document,'script',
'https://connect.facebook.net/en_US/fbevents.js');
fbq('init', 'XXXXXXXXXXXXX');
fbq('track', 'PageView');
</script>
<noscript><img height="1" width="1" style="display:none"
src="https://www.facebook.com/tr?id=XXXXXXXXXXXXX&ev=PageView&noscript=1"
/></noscript>
<!-- End Facebook Pixel Code -->
<script>
</script>
</body>
</html>
这就是它的“实现”方式,但它不起作用,至少 Facebook 小组是这么说的。
在使用 Angular 制作的 SPA 中执行此操作的正确方法是什么?
最佳答案
我遇到了同样的问题,并提出了以下解决方案。它仅适用于使用路由器的应用程序。希望有帮助:
在您的应用文件夹中为像素服务创建一个文件夹(例如 facebook-pixel-service),然后为服务代码创建文件(例如 facebook-pixel.service.ts)并复制以下代码工作原理如下:
- 应用程序第一次加载应用程序的根组件时,它将执行将 facebook 脚本附加到根组件 html 的操作。它还会调用 init 并触发当前页面的 PageView 事件(通常是路由器上的路径“/”)。
在与应用程序的其他路径/页面相对应的所有其他执行中,它只会触发 PageView 事件。
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class FacebookPixelService { private loadOk:boolean = false; constructor() { } load() { if (!this.loadOk) { (function (f: any, b, e, v, n, t, s) { if (f.fbq) return; n = f.fbq = function () { n.callMethod ? n.callMethod.apply(n, arguments) : n.queue.push(arguments) }; if (!f._fbq) f._fbq = n; n.push = n; n.loaded = !0; n.version = '2.0'; n.queue = []; t = b.createElement(e); t.async = !0; t.src = v; s = b.getElementsByTagName(e)[0]; s.parentNode.insertBefore(t, s) })(window, document, 'script', 'https://connect.facebook.net/en_US/fbevents.js'); (window as any).fbq.disablePushState = true; //not recommended, but can be done (window as any).fbq('init', '381817369337156'); (window as any).fbq('track', 'PageView'); this.loadOk = true; console.log('Facebook pixel init run!') } else { (window as any).fbq('track', 'PageView'); console.log('Facebook PageView event fired!') } } }
在服务的同一文件夹中为提供商创建另一个文件(例如 facebook-pixel.provider.ts),该文件将在 app.module 上注入(inject)服务。下面的代码将仅创建一个提供程序,该提供程序订阅每次触发 Router 事件时调用的像素服务,并且该事件是一个 NavigationEnd,这意味着它在路径/页面上成功更改。
import { Provider, APP_BOOTSTRAP_LISTENER, ComponentRef } from '@angular/core'; import { Router, NavigationEnd } from '@angular/router'; import { FacebookPixelService } from './facebook-pixel.service' export const FACEBOOK_PIXEL_PROVIDER: Provider = { provide: APP_BOOTSTRAP_LISTENER, multi: true, useFactory: FacebookPixelRouterInitializer, deps: [ FacebookPixelService, Router ] }; export function FacebookPixelRouterInitializer( $fpService: FacebookPixelService, $router: Router ) { return async (c: ComponentRef<any>) => { $router .events .subscribe(event => { if (event instanceof NavigationEnd) { console.log(`Navigated to URL: ${event.url}`); $fpService.load(); } }); }; }
现在,只需通知提供商 app.moudle 文件上的 @NgModule 指令即可。框架将完成剩下的工作,并确保它将我们的提供者订阅到路由器并在适当的时候调用它。下面的代码片段显示了如何通知提供商(搜索 FACEBOOK_PIXEL_PROVIDER):
... import { RouterModule, Routes } from '@angular/router'; ... import { AppComponent } from './app.component'; ... import { FACEBOOK_PIXEL_PROVIDER } from './facebook-pixel-service/facebook-pixel.provider' @NgModule({ declarations: [ AppComponent, ... ], imports: [ ... RouterModule.forRoot([ { path: '', Component: TheRootPath}, { path: 'path1', Component: Path1}, { path: 'path2', Component: Path2}, { path: '**', component: PageNotFoundComponent }, ]), ], providers: [ FACEBOOK_PIXEL_PROVIDER ], bootstrap: [AppComponent] }) export class AppModule { }
关于angular - 如何在 Angular 中实现 Facebook 像素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57318029/