2016-05-24 3 views
2

Извинения за тяжелый пост кода, но я хотел предоставить как можно больше контекста. У меня возникла проблема с определением службы в моем приложении Angular.js. Предполагается, что службы должны выступать в качестве синглтонов по всей заявке (source), поэтому я очень смущен, чтобы получить следующее поведение.AngularJS Service не действует как Singleton

В моем app.js файла, я бег моего AmplitudeService службы и console.log (AmplitudeService). Это выводит объект со всеми методами, которые я определил в моем файле AmplitudeService.js. Таким образом, я могу правильно использовать события службы и журнала, как и ожидалось.

Однако, когда я console.log (AmplitudeService) в моем header.js, он выводит мой объект Window. Таким образом, Окно не содержит таких функций, как «logEvent», «identUser» и т. Д., Поэтому AmplitudeService не может быть использован в этом случае.

Буду признателен за любую информацию!

AmplitudeService.js (source)

Примечание: Если проверить синтаксис автора, он возвращает объект в конце его службы. В своем исследовании я прочитал, чтобы использовать ключевое слово «this» при определении служебных функций (source) и что вам не нужно возвращать объект так же, как с Factory, поэтому я обновил его соответствующим образом.

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

    this.init = function() { 
    $amplitude.init(amplitudeApiKey, null); 
    $amplitude.logEvent('LAUNCHED_SITE', {page: $location.$$path}); 
    } 

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

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

углового amplitude.js (source)

Это позволяет получить доступ к "$" амплитудой на протяжении применения

(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'); 
console.log(AmplitudeService); // Outputs 'Object {}' 
}]) 

Header.js

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

$scope.goToSearch = function(term) { 
$location.path('/search/' + term); 
console.log(AmplitudeService); // Outputs 'Window {}' 
}; 
}]); 

ответ

3

Похоже, вы инъекционный $scope в контроллере, вызывая неожиданного отображение переменной

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

$scope.goToSearch = function(term) { 
$location.path('/search/' + term); 
console.log(AmplitudeService); // Outputs 'Window {}' 
}; 
}]); 

как в стороне, если найти этот формат гораздо проще для чтения/работы при определении контроллеров

angular 
    .module('app.common.header', []) 
    .controller('HeaderCtrl', headerController); 

headerController.$inject = [ '$rootScope', '$scope', '$location', '$route', '$window', 'AmplitudeService'] 

function headerController($rootScope, $scope, $location, $route, $window, AmplitudeService){ 
    $scope.goToSearch = function(term) { 
    $location.path('/search/' + term); 
    console.log(AmplitudeService); // Outputs 'Window {}' 
    }; 
} 
+0

Я думаю, мне нужен $ scope, но я мог ошибаться. Все мои функции (которые я разделил, чтобы сократить количество кода в этом сообщении) в Header.js, перечислены как функции $ scope. Например, $ scope.goToSearch (термин) перейдет на мою страницу поиска и будет искать этот термин. Эта функция вызывается в HTML, используя ng-submit = "goToSearch (term)". – zomp

+0

Я удалил инъекцию $ scope, но теперь у меня есть 7 неопределенных функций внутри этого контроллера. Любые другие предложения? Я ценю предыдущий комментарий. – zomp

+2

Вы дважды ввели «$ scope» - посмотрите, где я добавил «**» $ scope '** 'в вашем примере (пример первого кода). Удалите это определение, и вам должно быть хорошо идти. –

Смежные вопросы