2015-09-22 3 views
6

Мой Угловая приложение зависит от третьих сторон угловой службы:

var app = angular.module("ninjaModule", ['angular-google-analytics']); 

В приложение нагрузки просто отлично, до тех пор, как мои блокировки рекламы плагины отключены , Тем не менее, с ad-blockers на угловые броски ошибка $injector:nomod, не загружая все приложение.

Я ищу способ изящно обрабатывать эти ошибки и, следовательно, иметь возможность загружать приложение независимо от рекламных блоков. Если угловой-google-аналитики там не будет - отлично, это не критично, я могу справиться с этим или создать резервную копию. Но ситуация, когда все сбои приложений не подходит для меня. Есть идеи?

Чтобы быть точным - я не хочу работать с рекламными блоками, например. путем переименования моих файлов сценариев. Я ожидал бы уловки с уловкой.

Plunker: http://plnkr.co/edit/sbEG6vclPidPSNGV5Bsa

ответ

4

я, наконец, получил это работает. Решение требует несколько хаков, хотя:

  1. проверки, если угловой Google-аналитика загружается
  2. составления списка зависимостей (deps) для основного модуля на лету
  3. использованием $injector вместо Analytics явно

Тем не менее, мне нужно настроить AnalyticsProvider, но это должно быть относительно легко сделать с $injector.


var deps = []; 

try { 
    angular.module("angular-google-analytics"); // this throws if GA script is not loaded 
    deps.push('angular-google-analytics'); 
} catch(e){ console.error("GA not available", e); } 

angular.module('mainApp', deps) 
.run(function($rootScope, $injector) { 
    try { 
    Analytics = $injector.get('Analytics'); 
    $rootScope.trackPage = function() { 
     console.log('Analytics in action!'); 
     Analytics.trackPage(); 
    } 
    } catch(e) { 
    $rootScope.trackPage = function(key, label) { 
     console.log("Fallback in action!") 
    } 
    } 
}) 
.controller('MyCtrl', function($rootScope, $scope) { 
    $scope.message = 'Hello World!'; 
    $rootScope.trackPage(); 
}); 

Обновлено plunker: http://plnkr.co/edit/Zo4RgKOybzhvJQdW2nQZ?p=preview

+0

И идея очень похожа на этот ответ: http://stackoverflow.com/a/22173678/1640299 –

+0

Подтвержденные работы в моем приложении. Обратите внимание, что intellij Idea собирается жаловаться на то, что Analytics не определена, но игнорирует ошибку. –

2

Поскольку angular-google-analytics требует config блок настройки учетной записи, лучше всего, чтобы отделить Google Analytics отчетности в отдельный суб-модуль вашего приложения:

//create separate module for analytics reporting 
var reportingModule = angular.module('mainApp.reporting', [ 
    'angular-google-analytics' 
]) 
.config(function(AnalyticsProvider) { 
    AnalyticsProvider.setAccount('UA-HELLO-GA'); 
}) 
.run(function(Analytics) { 
    console.log('mmm.. analytics is good for you'); 
}); 

И тогда вставьте этот подмодуль в ваш основной модуль асинхронно через массив module.requires, поэтому он запускается после завершения начальной загрузки основного модуля:

var mainApp = angular.module('mainApp', [ 

]) 
.controller('MyCtrl', function($scope) { 
    $scope.message = 'Hello World!'; 
}); 

//set the dependency after app finished bootstrapping 
setTimeout(function() { 
    angular.module('mainApp').requires.push('myapp.reporting'); 
}, 1); 

Таким образом, основной модуль завершает загрузку без ошибок, связанных с сообщением подмодуля.

Вот раздвоенный версия вашего plunkr: http://plnkr.co/edit/lgNZOz4MZx0FGoCOGRC9

+0

Это выглядит многообещающим, но исключение не выброшен из 'angular.module)' метода (. Ни он не выбрасывается из 'app.requires.push()', поэтому попытка try-catch действительно не помогает. –

+0

На самом деле все вызовы 'app.config (...)', 'app.factory (...)', 'app.value (...)' успешно (хотя они, вероятно, являются асинхронными), и ошибка попадает позже из внутренних углов. –

+0

Я только что просмотрел ваш обновленный вопрос с помощью plunkr, и, поскольку я не знаком с угловыми Google Analytics, я не знал, что для установки учетной записи необходим блок 'config'. Это меняет ситуацию. Позвольте мне сделать некоторые исследования, и я уточню свой ответ. – yvesmancera

1

Принятый ответ ломает gulp dependency injection поэтому я итерацию на него, чтобы придумать более самостоятельно содержал метод (вы все равно нужно вводить тег сценария этого модуля вручную хотя, если вы полагаетесь на gulp-inject).

Вы можете добавить зависимость dynamically, и вы можете полностью избежать использования $injector.

angular.module('app', [ 
    'your', 
    'regular', 
    'dependencies' 
]) 
    .config(function(...) { 
     /*your normal code*/ 
    }) 
    .run(function(...) { 
     /*with no concern for analytics*/ 
    }) 
    //mimicking your answer for equivalence 
    .controller('MyCtrl', function($rootScope) { 
     if ($rootScope.Analytics) 
      $rootScope.Analytics.trackPage(); 
    }) 
; 


//protect against adblockers 
try { 
    //throws if not available 
    angular.module('angular-google-analytics'); 

    //dynamically add the dependency 
    angular.module('app').requires.push('angular-google-analytics'); 

    //set it up 
    angular.module('app') 
     .config(function (AnalyticsProvider) { 
      AnalyticsProvider.setAccount('UA-00000000-0'); 
     }) 
     //so we dont need to use $injector 
     .run(function(Analytics, $rootScope) { 
      $rootScope.Analytics = Analytics; 
     }) 
    ; 
} catch(e) { console.error('GA not available'); } 
Смежные вопросы