У меня есть служба под названием $doggedHttp
, которая предоставляет тот же интерфейс, что и $http
. Теперь я хочу создать услугу $doggedResource
, которая является угловым сервисом $resource
на верхней части $doggedHttp
вместо $http
. Другими словами, я хочу ввести $doggedHttp
в качестве услуги $http
.Переопределяющая зависимость во время выполнения в AngularJS
Кроме того, в моем приложении я хочу иметь возможность создавать как $doggedResource
, так и $resource
. Таким образом, я не могу просто переопределить $http
с $doggedHttp
.
Я думал, что инъекция зависимостей должна облегчить этот сценарий. Я ошибаюсь ?
Вместо этого мне пришлось углубиться в исходный код углового, наконец, придумал довольно уродливый решение:
angular.module('doggedResource', ['ngResource', 'doggedHttp'])
.config(function() {
var ngResource = angular.module('ngResource'),
doggedResource = angular.module('doggedResource');
// replace the placeholder below with the $resource factory from ngResource
doggedResource._invokeQueue[1][2][1][2] = ngResource._invokeQueue[0][2][1][2];
})
.factory('$doggedResource', ['$doggedHttp', '$parse', null /* this is just a placeholder */]);
Есть ли лучшее решение?
замечание, что мы не можем использовать $provide.decorator
заменить впрыскивается $http
услугу. Чтобы проиллюстрировать эту проблему, вот соответствующие части angular-resource.js:
angular.module('ngResource', ['ng']).
factory('$resource', ['$http', '$parse', function($http, $parse) {
function ResourceFactory(url, paramDefaults, actions) {
}
return ResourceFactory;
}
Глядя на коде выше $provide.decorator
обратный вызов будет передан ResourceFactory в качестве аргумента. В то время зависимость $http
уже разрешена. И так как ResourceFactory использует $http
внутри закрытия, мы не можем его изменить.
.config(function($provide) {
$provide.decorator('$resource', [ "$delegate", function($delegate) {
// here $delegate is the ResourceFactory which has
// already been linked to `$http` by a closure.
}
}
Итак, ваш «doggedHttp», это собственный модуль? Вы сделали angular.module («doggedHttp», [])? Вы не просто добавили завод в текущий модуль? – frosty
Просто из любопытства, зачем вам это нужно? Если это за издевательство во время модульного тестирования, есть лучшие способы сделать это. – ivarni
@aaronfrost yes 'doggedHttp' - это модуль, который определяет '$ doggedHttp' – recamshak