AngularJS 幅度服务不作为单例 [英] AngularJS Amplitude Service Not Acting as Singleton

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

问题描述

我最近发布了一个类似的问题,但这不是重复的.为代码繁重的帖子道歉,但我想提供尽可能多的上下文.我在将分析工具Amplitude"定义为 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

返回的对象相同的对象

将不胜感激任何和所有的见解!

附言官方 AmplitudeJS SDK 在这里.我正在尝试通过这个 wrapper 来实现它.

AmplitudeService.js(来源)

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

angular.module('AmplitudeService', []).service('振幅服务',['$amplitude', '$rootScope', 'amplitudeApiKey', '$location',函数($amplitude,$rootScope,amplitudeApiKey,$location){this.init = 函数(){$amplitude.init(amplitudeApiKey, null);}this.identifyUser = function(userId, userProperties) {$amplitude.setUserId(userId);$amplitude.setUserProperties(userProperties);}this.logEvent = 函数(事件名称,参数){$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) {(函数(e,t){var r = e.amplitude ||{};var n = t.createElement("脚本");n.type = "text/javascript";n.async = 真;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 = [];函数a(e){r[e] = 函数(){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. 振幅 = r})(窗口,文件);返回 $window.amplitude;}];}]);返回模块;}());

App.js

angular.module('app', ['ngRoute','角幅度','振幅服务',]).run(['AmplitudeService', function(AmplitudeService){控制台日志(振幅服务);//输出'对象{}'AmplitudeService.init();*AmplitudeService.logEvent('LAUNCHED_SITE');//这会记录事件*控制台日志(振幅服务);//输出'对象{}'}])

Header.js

 angular.module('app.common.header', []).controller('HeaderCtrl', [ '$rootScope', '$scope', '$location', '$route', '$window', 'AmplitudeService', function($rootScope, $scope, $location, $route, $window, AmplitudeService){$scope.goToSearch = 函数(术语){$location.path('/search/' + term);控制台日志(振幅服务);//输出'对象{}'*AmplitudeService.logEvent('SEARCHED');*//这不会记录事件};}]);

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

解决方案

找到了解决方案,希望这对遇到此问题的人有所帮助.我的解决方案是通过在 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天全站免登陆