【问题标题】:How to implement a facebook pixel in Angular?如何在 Angular 中实现 facebook 像素?
【发布时间】:2019-12-10 13:59:16
【问题描述】:

我需要在一个角度项目中实现一个 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 中执行此操作的正确方法是什么?

【问题讨论】:

    标签: angular facebook facebook-pixel


    【解决方案1】:

    我遇到了同样的问题,我想出了以下解决方案。它仅适用于使用路由器的应用程序。希望对您有所帮助:

    1. 在您的应用程序文件夹中为像素服务创建一个文件夹(例如 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!')
            }
          }
        }
        
    2. 在服务的同一文件夹中,为将在 app.module 上注入服务的提供者创建另一个文件(例如 facebook-pixel.provider.ts)。下面的代码将创建一个订阅我们的像素服务的提供程序,每次触发 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();
              }
            });
        };
      }
      
    3. 现在,只需将 app.moudle 文件中的 @NgModule 指令告知提供者即可。框架将完成剩下的工作,并确保它将我们的提供者订阅到路由器并在适当的时候调用它。下面的sn-p显示了如何通知提供者(搜索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 { }
      

    【讨论】:

    • 您好,此解决方案不适用于嵌套模块结构,其中父模块将延迟加载另一个模块...我们是否也需要将提供程序添加到子模块中?
    • 感谢您的服务!
    猜你喜欢
    • 2021-06-20
    • 2020-08-08
    • 2013-10-23
    • 1970-01-01
    • 2020-07-10
    • 1970-01-01
    • 1970-01-01
    • 2020-02-19
    • 2019-05-10
    相关资源
    最近更新 更多