Ответ 1
Провайдеры запускаются слишком рано до создания каких-либо сервисов или, другими словами, поставщик $get является конструктором службы и получает экземпляр после фазы конфигурации модуля (и когда он получает доступ в первый раз через инъекцию зависимостей, инжектор создает экземпляр конструктор и сохранить его как singleton). И провайдеры работают во время или до фазы конфигурации (поскольку методы провайдера используются для настройки службы во время фазы config
модуля). Это означает, что услуга $log пока недоступна.
$logProvider.$get
предоставит вам конструктор для logservice, вы можете сами создать его экземпляр, вызвав $injector.instantiate($logProvider.$get)
, но проблема в том, что он имеет зависимость от службы окна, которая еще не была создана, поэтому в конечном счете ваш регистратор
Итак, один из способов, о котором я мог только подумать, - получить $log от другого инжектора, т.е. angular.injector(['ng']).get('$log')
.
то есть
angular.module('my.module', [])
.provider('myProvider', function ($log, $logProvider) {
var $log = angular.injector(['ng']).get('$log');
$log.log("Aloha!");
this.$get = function($log) {
$log.log("Hello!"); // Everything is ok here
};
});
Или другой способ просто сойти с ума, создать его самостоятельно, создавая его зависимые сервисы, в этом случае это просто $window (или даже предоставить глобальное окно объект как локальные жители).
.provider('myProvider', function ($logProvider,$injector, $windowProvider) {
//get window service, if you want to really provide window service instance itself, or just provide the global window object
var window = $injector.instantiate($windowProvider.$get);
//Get log provider providing locals for $window
var $log = $injector.instantiate($logProvider.$get,{$window:window})
$log.log("Aloha!");// Everything is ok here too
this.$get = function($log) {
$log.log("Hello!"); // Everything is ok here
};
});
Просто добавьте другое примечание: вы увидите такое же поведение при попытке получить доступ к службе $log
во время фазы конфигурации приложения. Но иногда из-за работы decorators
вы все равно можете использовать его, заставляя раннее создание службы использовать фиктивный декоратор.
то есть:
.config(function($provide){
//Just a dummy decorator
$provide.decorator('$log', function($delegate){
return $delegate;
});
}).config(function($logProvider){
//get logger instance
var log = $logProvider.$get();
log.debug("Got it");
});
Итак, в конечном итоге идея состоит в том, что, когда вам нужно использовать службу до того, как она была создана, вам нужно будет вручную ее создать, разрешив все ее зависимости и т.д.