Я хочу добавить сервис в app.config, чтобы данные могли быть получены до вызова контроллера. Я попробовал это так:
Обслуживание:
app.service('dbService', function() {
return {
getData: function($q, $http) {
var defer = $q.defer();
$http.get('db.php/score/getData').success(function(data) {
defer.resolve(data);
});
return defer.promise;
}
};
});
Config:
app.config(function ($routeProvider, dbService) {
$routeProvider
.when('/',
{
templateUrl: "partials/editor.html",
controller: "AppCtrl",
resolve: {
data: dbService.getData(),
}
})
});
Но я получаю эту ошибку:
Ошибка: неизвестный поставщик: dbService из EditorApp
Как правильно настроить и внедрить этот сервис?
Ответы:
Алекс указал правильную причину неспособности сделать то, что вы пытаетесь сделать, поэтому +1. Но вы столкнулись с этой проблемой, потому что вы не совсем используете, решает, как они разработаны.
resolve
принимает либо строку службы, либо функцию, возвращающую значение для внедрения. Поскольку вы делаете последнее, вам нужно передать фактическую функцию:Когда фреймворк перейдет к разрешению
data
, он внедритdbService
в функцию, чтобы вы могли свободно ее использовать. Вам не нужно вводить вconfig
блок вообще, чтобы выполнить это.Приятного аппетита!
источник
.service
, так что двигайтесь$q
и$http
туда.pageData: 'myData'
, но тогда вам придется звонитьpageData.overview
с вашего контроллера. Строковый метод, вероятно, полезен только в том случае, если фабрика служб возвратила обещание вместо API. Таким образом, то, как вы сейчас это делаете, вероятно, лучший способ.Настройте свой сервис как пользовательский поставщик AngularJS
Несмотря на то, что говорится в ответе «Принято», вы на самом деле МОЖЕТЕ делать то, что намеревались сделать, но вам нужно настроить его в качестве настраиваемого поставщика, чтобы он был доступен в качестве службы на этапе настройки. Во-первых, измените
Service
его на поставщика. как показано ниже. Ключевым отличием здесь является то, что после установки значенияdefer
вы устанавливаетеdefer.promise
свойство для объекта обещания, возвращаемого$http.get
:Сервис провайдера: (провайдер: рецепт сервиса)
Теперь у вас есть настраиваемый пользовательский провайдер, вам просто нужно внедрить его. Ключевым отличием здесь является отсутствие «провайдера для инъекций».
конфигурации:
использовать разрешенные данные в вашем
appCtrl
Возможные альтернативы
Следующая альтернатива является аналогичным подходом, но позволяет определению происходить внутри
.config
, инкапсулируя службу в конкретном модуле в контексте вашего приложения. Выберите метод, который подходит именно вам. Также см. Ниже заметки о третьей альтернативе и полезные ссылки, которые помогут вам освоить все эти вещиНесколько полезных ресурсов
$http
конкретным в контексте этого запросаfactory
/service
/provider
на clevertech.biz .Провайдер предоставляет вам немного больше настроек по сравнению с
.service
методом, что делает его лучше в качестве провайдера уровня приложения, но вы также можете инкапсулировать это в самом объекте config, внедрив его$provide
в config следующим образом:источник
$get
вызова. Вместо этого вы хотите добавить методы в экземпляр провайдера и просто вернутьсяthis
при вызове$get
. Фактически, в вашем примере вы могли бы просто использовать сервис ... В провайдере вы также не можете вводить такие сервисы, как$http
. И, кстати, это//return the factory as a provider, that is available during the configuration phase
вводит в заблуждение / неверная информацияКраткий ответ: вы не можете. AngularJS не позволит вам внедрять сервисы в конфигурацию, потому что не может быть уверен, что они были загружены правильно.
Посмотрите этот вопрос и ответ: AngularJS-инъекция значения внутри модуля.config
источник
Я не думаю, что вы должны быть в состоянии сделать это, но я успешно внедрил службу в
config
блок. (AngularJS v1.0.7)источник
.config
вы написали cacheBuster (который нигде не определен в ответе) и dogmaCacheBusterProvider (который больше не используется). Вы проясните это?cacheBuster
определяется как параметр функции config. Что касаетсяdogmaCacheBusterProvider
того, что Angular делает с соглашениями об именах, что я давно забыл. Это может приблизить вас, stackoverflow.com/a/20881705/110010 ..provider()
рецепте. Что если я определю что-то с помощью.factory('ServiceName')
или.service('ServiceName')
рецептом и захочу использовать один из его методов в.config
блоке, установите параметр как ServiceNameProvider, но это остановит мое приложение.Вы можете использовать сервис $ inject для внедрения сервиса в вашу конфигурацию
Источник: http://odetocode.com/blogs/scott/archive/2014/04/21/better-error-handling-in-angularjs.aspx
источник
** Явно запрашивать услуги у других модулей, используя angular.injector **
Просто для уточнения ответа kim3er , вы можете предоставлять услуги, фабрики и т. Д., Не меняя их на провайдеров, если они включены в другие модули ...
Тем не менее, я не уверен,
*Provider
всегда ли будет доступен (который выполняется внутренне с помощью angular после того, как он обрабатывает сервис или фабрику) (это может зависеть от того, что еще загружено первым), так как угловые лениво загружают модули.Обратите внимание, что если вы хотите повторно ввести значения, они должны рассматриваться как константы.
Вот более явный и, вероятно, более надежный способ сделать это + рабочий поршень
источник
Использование $ инжектора для вызова методов службы в конфигурации
У меня была похожая проблема, и я решил ее с помощью службы $ injector, как показано выше. Я пытался внедрить сервис напрямую, но в итоге получал круговую зависимость от $ http. Сервис отображает модальное сообщение об ошибке, и я использую модальный интерфейс ui-bootstrap, который также зависит от $ https.
источник
Решение очень легко сделать это
Примечание : это только для асинхронного вызова, потому что служба не инициализируется при выполнении конфигурации.
Вы можете использовать
run()
метод. Пример :Ваш код :
источник
Ну, я немного боролся с этим, но я действительно сделал это.
Я не знаю, устарели ли ответы из-за некоторого изменения в угловых значениях, но вы можете сделать это следующим образом:
Это ваш сервис:
И это конфиг
источник
Самый простой способ:
$injector = angular.element(document.body).injector()
Затем используйте это для запуска
invoke()
илиget()
источник