AngularJS振幅服务不充当单例 [英] AngularJS Amplitude Service Not Acting as Singleton

查看:100
本文介绍了AngularJS振幅服务不充当单例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近发布了一个类似的问题,但这不是重复的. 对代码繁重的帖子表示歉意,但我想提供尽可能多的上下文.我在Angular.js应用程序中将分析工具振幅"定义为服务时遇到问题.服务应该在整个应用程序中充当单例(),所以我很困惑,得到以下行为.

在我的 app.js 文件中,我在.run函数中调用AmplitudeService.logEvent('EVENT_NAME'),该函数将事件成功记录到Amplitude中. 注意: Console.log(AmplitudeService)在此处返回具有所有正确功能的对象.

但是,当我在任何其他控制器(例如 header.js )中调用AmplitudeService.logEvent('EVENT_NAME')时,我在Amplitude仪表板中都看不到任何数据. 注意:Console.log(AmplitudeService)在 header.js 中返回与从 app.js

返回的对象相同的对象.

将不胜感激!

P.S.官方 AmplitudeJS SDK在这里.我正在尝试通过此包装器来实现它.

AmplitudeService.js ()

注意:如果检查作者的语法,他将在服务结束时返回一个对象.在我的研究中,我读过在定义服务功能时使用"this"关键字(),并且您不需要像使用Factory一样返回对象,因此我已对其进行了相应的更新.

angular.module('AmplitudeService', [])
.service('AmplitudeService', 
['$amplitude', '$rootScope', 'amplitudeApiKey', '$location',
function ($amplitude, $rootScope, amplitudeApiKey, $location) {

  this.init = function() {
    $amplitude.init(amplitudeApiKey, null);
  }

  this.identifyUser = function(userId, userProperties) {
    $amplitude.setUserId(userId);
    $amplitude.setUserProperties(userProperties);
  }

  this.logEvent = function(eventName, params) {
    $amplitude.logEvent(eventName, params);
  }
}]);

angular-amplitude.js ()

这允许在整个应用程序中访问"$ amplitude"

(function(){
var module = angular.module('angular-amplitude', ['ng']);

module.provider('$amplitude', [function $amplitudeProvider() {
this.$get = ['$window', function($window) {
  (function(e,t){
    var r = e.amplitude || {};
    var n = t.createElement("script");
    n.type = "text/javascript";
  n.async = true;
  n.src = "https://d24n15hnbwhuhn.buttfront.net/libs/amplitude-2.2.0-min.gz.js";
  var s = t.getElementsByTagName("script")[0];
  s.parentNode.insertBefore(n,s);
  r._q = [];

  function a(e){
    r[e] = function(){
      r._q.push([e].concat(Array.prototype.slice.call(arguments,0)));
    }
  }
  var i =    ["init","logEvent","logRevenue","setUserId","setUserProperties","setOptOut","setVersionName","setDomain","setDeviceId","setGlobalUserProperties"];
  for(var o = 0; o < i.length; o++){
    a(i[o])
  }
  e.amplitude = r
}
  )(window,document);
  return $window.amplitude;
}];
}]);
return module;
}());

App.js

angular.module('app', [
'ngRoute',
'angular-amplitude',
'AmplitudeService',
])

 .run(['AmplitudeService', function(AmplitudeService){
 console.log(AmplitudeService); // Outputs 'Object {}'
 AmplitudeService.init();
 *AmplitudeService.logEvent('LAUNCHED_SITE'); // This logs the event*
 console.log(AmplitudeService); // Outputs 'Object {}'
 }])

Header.js

  angular.module('app.common.header', [])
 .controller('HeaderCtrl', [ '$rootScope', '$scope', '$location','$route', '$window', 'AmplitudeService', function($rootScope, $scope, $location, $route, $window, AmplitudeService){

 $scope.goToSearch = function(term) {
 $location.path('/search/' + term);
  console.log(AmplitudeService); // Outputs 'Object {}'
*AmplitudeService.logEvent('SEARCHED');* // This does not log the event
 };
 }]);

更新:我已尝试将服务切换到工厂,但未产生任何新结果.

解决方案

找到了解决方案,并希望这对遇到此问题的任何人有所帮助.我的解决方案是通过在app.js的.run()函数内调用AmplitudeService.init()来初始化SDK,该函数在我的窗口中初始化了一个幅值对象.从那以后,我将$ window作为服务包含在每个控制器中,并称为$ window.amplitude.logEvent('event_name_here');

如有疑问,请随时联系.谢谢.

I have recently posted a similar question, but this is not a duplicate. Apologies for the code heavy post but I wanted to provide as much context as possible. I am having an issue with defining the analytics tool, 'Amplitude' as a service in my Angular.js application. Services are supposed to act as singletons throughout an application (source), so I am confused to be getting the following behavior.

In my app.js file, I call AmplitudeService.logEvent('EVENT_NAME') in a .run function which successfully logs the event to Amplitude. Note: Console.log(AmplitudeService) returns an object with all the correct functions here.

However, when I call AmplitudeService.logEvent('EVENT_NAME') within any other controller, such as header.js I do not ever see any data in my Amplitude dashboard. Note: Console.log(AmplitudeService) returns an identical object within header.js to the one returned from app.js

Would appreciate any and all insight!

P.S. The official AmplitudeJS SDK is here. I am trying to implement it through this wrapper.

AmplitudeService.js (source)

Note: If you check the author's syntax, he returns an object at the end of his service. In my research, I've read to use the "this" keyword when defining Service functions (source), and that you don't need to return an object as you would with a Factory, so I have updated it accordingly.

angular.module('AmplitudeService', [])
.service('AmplitudeService', 
['$amplitude', '$rootScope', 'amplitudeApiKey', '$location',
function ($amplitude, $rootScope, amplitudeApiKey, $location) {

  this.init = function() {
    $amplitude.init(amplitudeApiKey, null);
  }

  this.identifyUser = function(userId, userProperties) {
    $amplitude.setUserId(userId);
    $amplitude.setUserProperties(userProperties);
  }

  this.logEvent = function(eventName, params) {
    $amplitude.logEvent(eventName, params);
  }
}]);

angular-amplitude.js (source)

This allows access to "$amplitude" throughout the application

(function(){
var module = angular.module('angular-amplitude', ['ng']);

module.provider('$amplitude', [function $amplitudeProvider() {
this.$get = ['$window', function($window) {
  (function(e,t){
    var r = e.amplitude || {};
    var n = t.createElement("script");
    n.type = "text/javascript";
  n.async = true;
  n.src = "https://d24n15hnbwhuhn.buttfront.net/libs/amplitude-2.2.0-min.gz.js";
  var s = t.getElementsByTagName("script")[0];
  s.parentNode.insertBefore(n,s);
  r._q = [];

  function a(e){
    r[e] = function(){
      r._q.push([e].concat(Array.prototype.slice.call(arguments,0)));
    }
  }
  var i =    ["init","logEvent","logRevenue","setUserId","setUserProperties","setOptOut","setVersionName","setDomain","setDeviceId","setGlobalUserProperties"];
  for(var o = 0; o < i.length; o++){
    a(i[o])
  }
  e.amplitude = r
}
  )(window,document);
  return $window.amplitude;
}];
}]);
return module;
}());

App.js

angular.module('app', [
'ngRoute',
'angular-amplitude',
'AmplitudeService',
])

 .run(['AmplitudeService', function(AmplitudeService){
 console.log(AmplitudeService); // Outputs 'Object {}'
 AmplitudeService.init();
 *AmplitudeService.logEvent('LAUNCHED_SITE'); // This logs the event*
 console.log(AmplitudeService); // Outputs 'Object {}'
 }])

Header.js

  angular.module('app.common.header', [])
 .controller('HeaderCtrl', [ '$rootScope', '$scope', '$location','$route', '$window', 'AmplitudeService', function($rootScope, $scope, $location, $route, $window, AmplitudeService){

 $scope.goToSearch = function(term) {
 $location.path('/search/' + term);
  console.log(AmplitudeService); // Outputs 'Object {}'
*AmplitudeService.logEvent('SEARCHED');* // This does not log the event
 };
 }]);

Update: I have tried switching the Service to a Factory and that did not generate any new results.

解决方案

Found the solution and hope this is helpful to anyone that comes across this. My solution was to initialize the SDK by calling AmplitudeService.init() within a .run() function within app.js, which initialized an amplitude object within my window. From there forward, I included $window as a service in each of my controllers and called $window.amplitude.logEvent('event_name_here');

Feel free to contact if you have questions. Thanks.

这篇关于AngularJS振幅服务不充当单例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆